Update upstream source from tag 'upstream/1.2.5.1'
Update to upstream version '1.2.5.1'
with Debian dir b88efb9f906751433bf9d15dbc0ef3ce9d4b0c21
Jordi Mallach
2 years ago
15 | 15 | endif |
16 | 16 | endif |
17 | 17 | SUBDIRS += test utils |
18 | EXTRA_DIST=ChangeLog INSTALL TODO NOTES configure gitcompile libtool \ | |
18 | EXTRA_DIST=README.md ChangeLog INSTALL TODO NOTES configure gitcompile libtool \ | |
19 | 19 | depcomp version MEMORY-LEAK m4/attributes.m4 |
20 | 20 | AUTOMAKE_OPTIONS=foreign |
21 | 21 |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
331 | 331 | prefix = @prefix@ |
332 | 332 | program_transform_name = @program_transform_name@ |
333 | 333 | psdir = @psdir@ |
334 | runstatedir = @runstatedir@ | |
334 | 335 | sbindir = @sbindir@ |
335 | 336 | sharedstatedir = @sharedstatedir@ |
336 | 337 | srcdir = @srcdir@ |
342 | 343 | ACLOCAL_AMFLAGS = -I m4 |
343 | 344 | SUBDIRS = doc include src $(am__append_1) $(am__append_2) \ |
344 | 345 | $(am__append_3) $(am__append_4) test utils |
345 | EXTRA_DIST = ChangeLog INSTALL TODO NOTES configure gitcompile libtool \ | |
346 | EXTRA_DIST = README.md ChangeLog INSTALL TODO NOTES configure gitcompile libtool \ | |
346 | 347 | depcomp version MEMORY-LEAK m4/attributes.m4 |
347 | 348 | |
348 | 349 | AUTOMAKE_OPTIONS = foreign |
585 | 586 | tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz |
586 | 587 | $(am__post_remove_distdir) |
587 | 588 | |
589 | dist-zstd: distdir | |
590 | tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst | |
591 | $(am__post_remove_distdir) | |
592 | ||
588 | 593 | dist-tarZ: distdir |
589 | 594 | @echo WARNING: "Support for distribution archives compressed with" \ |
590 | 595 | "legacy program 'compress' is deprecated." >&2 |
627 | 632 | eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ |
628 | 633 | *.zip*) \ |
629 | 634 | unzip $(distdir).zip ;;\ |
635 | *.tar.zst*) \ | |
636 | zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ | |
630 | 637 | esac |
631 | 638 | chmod -R a-w $(distdir) |
632 | 639 | chmod u+w $(distdir) |
804 | 811 | am--refresh check check-am clean clean-cscope clean-generic \ |
805 | 812 | clean-libtool cscope cscopelist-am ctags ctags-am dist \ |
806 | 813 | dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ |
807 | dist-tarZ dist-xz dist-zip distcheck distclean \ | |
814 | dist-tarZ dist-xz dist-zip dist-zstd distcheck distclean \ | |
808 | 815 | distclean-generic distclean-libtool distclean-tags \ |
809 | 816 | distcleancheck distdir distuninstallcheck dvi dvi-am html \ |
810 | 817 | html-am info info-am install install-am install-data \ |
0 | # alsa-lib | |
1 | ## Advanced Linux Sound Architecture (ALSA) project | |
2 | ||
3 | ![Build alsa-lib](https://github.com/alsa-project/alsa-lib/workflows/Build%20alsa-lib/badge.svg?branch=master) | |
4 | ||
5 | The alsa-lib is a library to interface with ALSA in the Linux kernel and | |
6 | virtual devices using a plugin system. | |
7 | ||
8 | The up-to-date reference generated from sources can be accessed here: | |
9 | ||
10 | http://www.alsa-project.org/alsa-doc/alsa-lib/ | |
11 | ||
12 | You may give a look for more information about the ALSA project to URL | |
13 | http://www.alsa-project.org. | |
14 | ||
15 | ### Submitting patches | |
16 | ||
17 | The preferred way to submit patches is by sending them by email to the | |
18 | alsa-devel mailing list. Sending mail to the list requires subscription, | |
19 | subscribe here: https://mailman.alsa-project.org/mailman/listinfo/alsa-devel | |
20 | ||
21 | Add Takashi Iwai `<tiwai@suse.de>` and/or Jaroslav Kysela `<perex@perex.cz>` to | |
22 | Cc so that your patch won't be missed. | |
23 | ||
24 | Patches are also accepted as GitHub pull requests. |
0 | # generated automatically by aclocal 1.16.1 -*- Autoconf -*- | |
1 | ||
2 | # Copyright (C) 1996-2018 Free Software Foundation, Inc. | |
0 | # generated automatically by aclocal 1.16.2 -*- Autoconf -*- | |
1 | ||
2 | # Copyright (C) 1996-2020 Free Software Foundation, Inc. | |
3 | 3 | |
4 | 4 | # This file is free software; the Free Software Foundation |
5 | 5 | # gives unlimited permission to copy and/or distribute it, |
19 | 19 | If you have problems, you may need to regenerate the build system entirely. |
20 | 20 | To do so, use the procedure documented by the package, typically 'autoreconf'.])]) |
21 | 21 | |
22 | # Copyright (C) 2002-2018 Free Software Foundation, Inc. | |
22 | # Copyright (C) 2002-2020 Free Software Foundation, Inc. | |
23 | 23 | # |
24 | 24 | # This file is free software; the Free Software Foundation |
25 | 25 | # gives unlimited permission to copy and/or distribute it, |
34 | 34 | [am__api_version='1.16' |
35 | 35 | dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to |
36 | 36 | dnl require some minimum version. Point them to the right macro. |
37 | m4_if([$1], [1.16.1], [], | |
37 | m4_if([$1], [1.16.2], [], | |
38 | 38 | [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl |
39 | 39 | ]) |
40 | 40 | |
50 | 50 | # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. |
51 | 51 | # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. |
52 | 52 | AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], |
53 | [AM_AUTOMAKE_VERSION([1.16.1])dnl | |
53 | [AM_AUTOMAKE_VERSION([1.16.2])dnl | |
54 | 54 | m4_ifndef([AC_AUTOCONF_VERSION], |
55 | 55 | [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl |
56 | 56 | _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) |
57 | 57 | |
58 | 58 | # AM_AUX_DIR_EXPAND -*- Autoconf -*- |
59 | 59 | |
60 | # Copyright (C) 2001-2018 Free Software Foundation, Inc. | |
60 | # Copyright (C) 2001-2020 Free Software Foundation, Inc. | |
61 | 61 | # |
62 | 62 | # This file is free software; the Free Software Foundation |
63 | 63 | # gives unlimited permission to copy and/or distribute it, |
109 | 109 | |
110 | 110 | # AM_CONDITIONAL -*- Autoconf -*- |
111 | 111 | |
112 | # Copyright (C) 1997-2018 Free Software Foundation, Inc. | |
112 | # Copyright (C) 1997-2020 Free Software Foundation, Inc. | |
113 | 113 | # |
114 | 114 | # This file is free software; the Free Software Foundation |
115 | 115 | # gives unlimited permission to copy and/or distribute it, |
140 | 140 | Usually this means the macro was only invoked conditionally.]]) |
141 | 141 | fi])]) |
142 | 142 | |
143 | # Copyright (C) 1999-2018 Free Software Foundation, Inc. | |
143 | # Copyright (C) 1999-2020 Free Software Foundation, Inc. | |
144 | 144 | # |
145 | 145 | # This file is free software; the Free Software Foundation |
146 | 146 | # gives unlimited permission to copy and/or distribute it, |
331 | 331 | |
332 | 332 | # Generate code to set up dependency tracking. -*- Autoconf -*- |
333 | 333 | |
334 | # Copyright (C) 1999-2018 Free Software Foundation, Inc. | |
334 | # Copyright (C) 1999-2020 Free Software Foundation, Inc. | |
335 | 335 | # |
336 | 336 | # This file is free software; the Free Software Foundation |
337 | 337 | # gives unlimited permission to copy and/or distribute it, |
370 | 370 | done |
371 | 371 | if test $am_rc -ne 0; then |
372 | 372 | AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments |
373 | for automatic dependency tracking. Try re-running configure with the | |
373 | for automatic dependency tracking. If GNU make was not used, consider | |
374 | re-running the configure script with MAKE="gmake" (or whatever is | |
375 | necessary). You can also try re-running configure with the | |
374 | 376 | '--disable-dependency-tracking' option to at least be able to build |
375 | 377 | the package (albeit without support for automatic dependency tracking).]) |
376 | 378 | fi |
397 | 399 | |
398 | 400 | # Do all the work for Automake. -*- Autoconf -*- |
399 | 401 | |
400 | # Copyright (C) 1996-2018 Free Software Foundation, Inc. | |
402 | # Copyright (C) 1996-2020 Free Software Foundation, Inc. | |
401 | 403 | # |
402 | 404 | # This file is free software; the Free Software Foundation |
403 | 405 | # gives unlimited permission to copy and/or distribute it, |
594 | 596 | done |
595 | 597 | echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) |
596 | 598 | |
597 | # Copyright (C) 2001-2018 Free Software Foundation, Inc. | |
599 | # Copyright (C) 2001-2020 Free Software Foundation, Inc. | |
598 | 600 | # |
599 | 601 | # This file is free software; the Free Software Foundation |
600 | 602 | # gives unlimited permission to copy and/or distribute it, |
615 | 617 | fi |
616 | 618 | AC_SUBST([install_sh])]) |
617 | 619 | |
618 | # Copyright (C) 2003-2018 Free Software Foundation, Inc. | |
620 | # Copyright (C) 2003-2020 Free Software Foundation, Inc. | |
619 | 621 | # |
620 | 622 | # This file is free software; the Free Software Foundation |
621 | 623 | # gives unlimited permission to copy and/or distribute it, |
637 | 639 | # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- |
638 | 640 | # From Jim Meyering |
639 | 641 | |
640 | # Copyright (C) 1996-2018 Free Software Foundation, Inc. | |
642 | # Copyright (C) 1996-2020 Free Software Foundation, Inc. | |
641 | 643 | # |
642 | 644 | # This file is free software; the Free Software Foundation |
643 | 645 | # gives unlimited permission to copy and/or distribute it, |
672 | 674 | |
673 | 675 | # Check to see how 'make' treats includes. -*- Autoconf -*- |
674 | 676 | |
675 | # Copyright (C) 2001-2018 Free Software Foundation, Inc. | |
677 | # Copyright (C) 2001-2020 Free Software Foundation, Inc. | |
676 | 678 | # |
677 | 679 | # This file is free software; the Free Software Foundation |
678 | 680 | # gives unlimited permission to copy and/or distribute it, |
715 | 717 | |
716 | 718 | # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- |
717 | 719 | |
718 | # Copyright (C) 1997-2018 Free Software Foundation, Inc. | |
720 | # Copyright (C) 1997-2020 Free Software Foundation, Inc. | |
719 | 721 | # |
720 | 722 | # This file is free software; the Free Software Foundation |
721 | 723 | # gives unlimited permission to copy and/or distribute it, |
754 | 756 | |
755 | 757 | # Helper functions for option handling. -*- Autoconf -*- |
756 | 758 | |
757 | # Copyright (C) 2001-2018 Free Software Foundation, Inc. | |
759 | # Copyright (C) 2001-2020 Free Software Foundation, Inc. | |
758 | 760 | # |
759 | 761 | # This file is free software; the Free Software Foundation |
760 | 762 | # gives unlimited permission to copy and/or distribute it, |
783 | 785 | AC_DEFUN([_AM_IF_OPTION], |
784 | 786 | [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) |
785 | 787 | |
786 | # Copyright (C) 1999-2018 Free Software Foundation, Inc. | |
788 | # Copyright (C) 1999-2020 Free Software Foundation, Inc. | |
787 | 789 | # |
788 | 790 | # This file is free software; the Free Software Foundation |
789 | 791 | # gives unlimited permission to copy and/or distribute it, |
830 | 832 | # For backward compatibility. |
831 | 833 | AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) |
832 | 834 | |
833 | # Copyright (C) 2001-2018 Free Software Foundation, Inc. | |
835 | # Copyright (C) 2001-2020 Free Software Foundation, Inc. | |
834 | 836 | # |
835 | 837 | # This file is free software; the Free Software Foundation |
836 | 838 | # gives unlimited permission to copy and/or distribute it, |
849 | 851 | |
850 | 852 | # Check to make sure that the build environment is sane. -*- Autoconf -*- |
851 | 853 | |
852 | # Copyright (C) 1996-2018 Free Software Foundation, Inc. | |
854 | # Copyright (C) 1996-2020 Free Software Foundation, Inc. | |
853 | 855 | # |
854 | 856 | # This file is free software; the Free Software Foundation |
855 | 857 | # gives unlimited permission to copy and/or distribute it, |
930 | 932 | rm -f conftest.file |
931 | 933 | ]) |
932 | 934 | |
933 | # Copyright (C) 2009-2018 Free Software Foundation, Inc. | |
935 | # Copyright (C) 2009-2020 Free Software Foundation, Inc. | |
934 | 936 | # |
935 | 937 | # This file is free software; the Free Software Foundation |
936 | 938 | # gives unlimited permission to copy and/or distribute it, |
990 | 992 | _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl |
991 | 993 | ]) |
992 | 994 | |
993 | # Copyright (C) 2001-2018 Free Software Foundation, Inc. | |
995 | # Copyright (C) 2001-2020 Free Software Foundation, Inc. | |
994 | 996 | # |
995 | 997 | # This file is free software; the Free Software Foundation |
996 | 998 | # gives unlimited permission to copy and/or distribute it, |
1018 | 1020 | INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" |
1019 | 1021 | AC_SUBST([INSTALL_STRIP_PROGRAM])]) |
1020 | 1022 | |
1021 | # Copyright (C) 2006-2018 Free Software Foundation, Inc. | |
1023 | # Copyright (C) 2006-2020 Free Software Foundation, Inc. | |
1022 | 1024 | # |
1023 | 1025 | # This file is free software; the Free Software Foundation |
1024 | 1026 | # gives unlimited permission to copy and/or distribute it, |
1037 | 1039 | |
1038 | 1040 | # Check how to create a tarball. -*- Autoconf -*- |
1039 | 1041 | |
1040 | # Copyright (C) 2004-2018 Free Software Foundation, Inc. | |
1042 | # Copyright (C) 2004-2020 Free Software Foundation, Inc. | |
1041 | 1043 | # |
1042 | 1044 | # This file is free software; the Free Software Foundation |
1043 | 1045 | # gives unlimited permission to copy and/or distribute it, |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
295 | 295 | prefix = @prefix@ |
296 | 296 | program_transform_name = @program_transform_name@ |
297 | 297 | psdir = @psdir@ |
298 | runstatedir = @runstatedir@ | |
298 | 299 | sbindir = @sbindir@ |
299 | 300 | sharedstatedir = @sharedstatedir@ |
300 | 301 | srcdir = @srcdir@ |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
296 | 296 | prefix = @prefix@ |
297 | 297 | program_transform_name = @program_transform_name@ |
298 | 298 | psdir = @psdir@ |
299 | runstatedir = @runstatedir@ | |
299 | 300 | sbindir = @sbindir@ |
300 | 301 | sharedstatedir = @sharedstatedir@ |
301 | 302 | srcdir = @srcdir@ |
2 | 2 | |
3 | 3 | scriptversion=2018-03-07.03; # UTC |
4 | 4 | |
5 | # Copyright (C) 1999-2018 Free Software Foundation, Inc. | |
5 | # Copyright (C) 1999-2020 Free Software Foundation, Inc. | |
6 | 6 | # Written by Tom Tromey <tromey@cygnus.com>. |
7 | 7 | # |
8 | 8 | # This program is free software; you can redistribute it and/or modify |
52 | 52 | MINGW*) |
53 | 53 | file_conv=mingw |
54 | 54 | ;; |
55 | CYGWIN*) | |
55 | CYGWIN* | MSYS*) | |
56 | 56 | file_conv=cygwin |
57 | 57 | ;; |
58 | 58 | *) |
66 | 66 | mingw/*) |
67 | 67 | file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` |
68 | 68 | ;; |
69 | cygwin/*) | |
69 | cygwin/* | msys/*) | |
70 | 70 | file=`cygpath -m "$file" || echo "$file"` |
71 | 71 | ;; |
72 | 72 | wine/*) |
1 | 1 | # Attempt to guess a canonical system name. |
2 | 2 | # Copyright 1992-2018 Free Software Foundation, Inc. |
3 | 3 | |
4 | timestamp='2018-03-08' | |
4 | timestamp='2018-08-29' | |
5 | 5 | |
6 | 6 | # This file is free software; you can redistribute it and/or modify it |
7 | 7 | # under the terms of the GNU General Public License as published by |
83 | 83 | exit 1 |
84 | 84 | fi |
85 | 85 | |
86 | trap 'exit 1' 1 2 15 | |
87 | ||
88 | 86 | # CC_FOR_BUILD -- compiler used by this script. Note that the use of a |
89 | 87 | # compiler to aid in system detection is discouraged as it requires |
90 | 88 | # temporary files to be created and, as you can see below, it is a |
95 | 93 | |
96 | 94 | # Portable tmp directory creation inspired by the Autoconf team. |
97 | 95 | |
98 | set_cc_for_build=' | |
99 | trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; | |
100 | trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; | |
101 | : ${TMPDIR=/tmp} ; | |
102 | { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || | |
103 | { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || | |
104 | { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || | |
105 | { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; | |
106 | dummy=$tmp/dummy ; | |
107 | tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; | |
108 | case $CC_FOR_BUILD,$HOST_CC,$CC in | |
109 | ,,) echo "int x;" > "$dummy.c" ; | |
110 | for c in cc gcc c89 c99 ; do | |
111 | if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then | |
112 | CC_FOR_BUILD="$c"; break ; | |
113 | fi ; | |
114 | done ; | |
115 | if test x"$CC_FOR_BUILD" = x ; then | |
116 | CC_FOR_BUILD=no_compiler_found ; | |
117 | fi | |
118 | ;; | |
119 | ,,*) CC_FOR_BUILD=$CC ;; | |
120 | ,*,*) CC_FOR_BUILD=$HOST_CC ;; | |
121 | esac ; set_cc_for_build= ;' | |
96 | tmp= | |
97 | # shellcheck disable=SC2172 | |
98 | trap 'test -z "$tmp" || rm -fr "$tmp"' 1 2 13 15 | |
99 | trap 'exitcode=$?; test -z "$tmp" || rm -fr "$tmp"; exit $exitcode' 0 | |
100 | ||
101 | set_cc_for_build() { | |
102 | : "${TMPDIR=/tmp}" | |
103 | # shellcheck disable=SC2039 | |
104 | { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || | |
105 | { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || | |
106 | { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || | |
107 | { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } | |
108 | dummy=$tmp/dummy | |
109 | case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in | |
110 | ,,) echo "int x;" > "$dummy.c" | |
111 | for driver in cc gcc c89 c99 ; do | |
112 | if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then | |
113 | CC_FOR_BUILD="$driver" | |
114 | break | |
115 | fi | |
116 | done | |
117 | if test x"$CC_FOR_BUILD" = x ; then | |
118 | CC_FOR_BUILD=no_compiler_found | |
119 | fi | |
120 | ;; | |
121 | ,,*) CC_FOR_BUILD=$CC ;; | |
122 | ,*,*) CC_FOR_BUILD=$HOST_CC ;; | |
123 | esac | |
124 | } | |
122 | 125 | |
123 | 126 | # This is needed to find uname on a Pyramid OSx when run in the BSD universe. |
124 | 127 | # (ghazi@noc.rutgers.edu 1994-08-24) |
125 | if (test -f /.attbin/uname) >/dev/null 2>&1 ; then | |
128 | if test -f /.attbin/uname ; then | |
126 | 129 | PATH=$PATH:/.attbin ; export PATH |
127 | 130 | fi |
128 | 131 | |
137 | 140 | # We could probably try harder. |
138 | 141 | LIBC=gnu |
139 | 142 | |
140 | eval "$set_cc_for_build" | |
143 | set_cc_for_build | |
141 | 144 | cat <<-EOF > "$dummy.c" |
142 | 145 | #include <features.h> |
143 | 146 | #if defined(__UCLIBC__) |
198 | 201 | os=netbsdelf |
199 | 202 | ;; |
200 | 203 | arm*|i386|m68k|ns32k|sh3*|sparc|vax) |
201 | eval "$set_cc_for_build" | |
204 | set_cc_for_build | |
202 | 205 | if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ |
203 | 206 | | grep -q __ELF__ |
204 | 207 | then |
236 | 239 | # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: |
237 | 240 | # contains redundant information, the shorter form: |
238 | 241 | # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. |
239 | echo "$machine-${os}${release}${abi}" | |
242 | echo "$machine-${os}${release}${abi-}" | |
240 | 243 | exit ;; |
241 | 244 | *:Bitrig:*:*) |
242 | 245 | UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` |
388 | 391 | echo i386-pc-auroraux"$UNAME_RELEASE" |
389 | 392 | exit ;; |
390 | 393 | i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) |
391 | eval "$set_cc_for_build" | |
392 | SUN_ARCH=i386 | |
393 | # If there is a compiler, see if it is configured for 64-bit objects. | |
394 | # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. | |
395 | # This test works for both compilers. | |
396 | if [ "$CC_FOR_BUILD" != no_compiler_found ]; then | |
397 | if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ | |
398 | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ | |
399 | grep IS_64BIT_ARCH >/dev/null | |
400 | then | |
401 | SUN_ARCH=x86_64 | |
402 | fi | |
403 | fi | |
404 | echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" | |
394 | UNAME_REL="`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" | |
395 | case `isainfo -b` in | |
396 | 32) | |
397 | echo i386-pc-solaris2"$UNAME_REL" | |
398 | ;; | |
399 | 64) | |
400 | echo x86_64-pc-solaris2"$UNAME_REL" | |
401 | ;; | |
402 | esac | |
405 | 403 | exit ;; |
406 | 404 | sun4*:SunOS:6*:*) |
407 | 405 | # According to config.sub, this is the proper way to canonicalize |
481 | 479 | echo clipper-intergraph-clix"$UNAME_RELEASE" |
482 | 480 | exit ;; |
483 | 481 | mips:*:*:UMIPS | mips:*:*:RISCos) |
484 | eval "$set_cc_for_build" | |
482 | set_cc_for_build | |
485 | 483 | sed 's/^ //' << EOF > "$dummy.c" |
486 | 484 | #ifdef __cplusplus |
487 | 485 | #include <stdio.h> /* for printf() prototype */ |
578 | 576 | exit ;; |
579 | 577 | *:AIX:2:3) |
580 | 578 | if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then |
581 | eval "$set_cc_for_build" | |
579 | set_cc_for_build | |
582 | 580 | sed 's/^ //' << EOF > "$dummy.c" |
583 | 581 | #include <sys/systemcfg.h> |
584 | 582 | |
659 | 657 | esac |
660 | 658 | fi |
661 | 659 | if [ "$HP_ARCH" = "" ]; then |
662 | eval "$set_cc_for_build" | |
660 | set_cc_for_build | |
663 | 661 | sed 's/^ //' << EOF > "$dummy.c" |
664 | 662 | |
665 | 663 | #define _HPUX_SOURCE |
699 | 697 | esac |
700 | 698 | if [ "$HP_ARCH" = hppa2.0w ] |
701 | 699 | then |
702 | eval "$set_cc_for_build" | |
700 | set_cc_for_build | |
703 | 701 | |
704 | 702 | # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating |
705 | 703 | # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler |
725 | 723 | echo ia64-hp-hpux"$HPUX_REV" |
726 | 724 | exit ;; |
727 | 725 | 3050*:HI-UX:*:*) |
728 | eval "$set_cc_for_build" | |
726 | set_cc_for_build | |
729 | 727 | sed 's/^ //' << EOF > "$dummy.c" |
730 | 728 | #include <unistd.h> |
731 | 729 | int |
839 | 837 | *:BSD/OS:*:*) |
840 | 838 | echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" |
841 | 839 | exit ;; |
840 | arm:FreeBSD:*:*) | |
841 | UNAME_PROCESSOR=`uname -p` | |
842 | set_cc_for_build | |
843 | if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | |
844 | | grep -q __ARM_PCS_VFP | |
845 | then | |
846 | echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi | |
847 | else | |
848 | echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf | |
849 | fi | |
850 | exit ;; | |
842 | 851 | *:FreeBSD:*:*) |
843 | 852 | UNAME_PROCESSOR=`/usr/bin/uname -p` |
844 | 853 | case "$UNAME_PROCESSOR" in |
893 | 902 | # other systems with GNU libc and userland |
894 | 903 | echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" |
895 | 904 | exit ;; |
896 | i*86:Minix:*:*) | |
897 | echo "$UNAME_MACHINE"-pc-minix | |
905 | *:Minix:*:*) | |
906 | echo "$UNAME_MACHINE"-unknown-minix | |
898 | 907 | exit ;; |
899 | 908 | aarch64:Linux:*:*) |
900 | 909 | echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" |
921 | 930 | echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" |
922 | 931 | exit ;; |
923 | 932 | arm*:Linux:*:*) |
924 | eval "$set_cc_for_build" | |
933 | set_cc_for_build | |
925 | 934 | if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ |
926 | 935 | | grep -q __ARM_EABI__ |
927 | 936 | then |
970 | 979 | echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" |
971 | 980 | exit ;; |
972 | 981 | mips:Linux:*:* | mips64:Linux:*:*) |
973 | eval "$set_cc_for_build" | |
982 | set_cc_for_build | |
974 | 983 | sed 's/^ //' << EOF > "$dummy.c" |
975 | 984 | #undef CPU |
976 | 985 | #undef ${UNAME_MACHINE} |
1284 | 1293 | exit ;; |
1285 | 1294 | *:Darwin:*:*) |
1286 | 1295 | UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown |
1287 | eval "$set_cc_for_build" | |
1296 | set_cc_for_build | |
1288 | 1297 | if test "$UNAME_PROCESSOR" = unknown ; then |
1289 | 1298 | UNAME_PROCESSOR=powerpc |
1290 | 1299 | fi |
1357 | 1366 | # "uname -m" is not consistent, so use $cputype instead. 386 |
1358 | 1367 | # is converted to i386 for consistency with other x86 |
1359 | 1368 | # operating systems. |
1369 | # shellcheck disable=SC2154 | |
1360 | 1370 | if test "$cputype" = 386; then |
1361 | 1371 | UNAME_MACHINE=i386 |
1362 | 1372 | else |
1 | 1 | # Configuration validation subroutine script. |
2 | 2 | # Copyright 1992-2018 Free Software Foundation, Inc. |
3 | 3 | |
4 | timestamp='2018-05-05' | |
4 | timestamp='2018-08-29' | |
5 | 5 | |
6 | 6 | # This file is free software; you can redistribute it and/or modify it |
7 | 7 | # under the terms of the GNU General Public License as published by |
109 | 109 | exit 1;; |
110 | 110 | esac |
111 | 111 | |
112 | # Spilt fields of configuration type | |
112 | # Split fields of configuration type | |
113 | 113 | IFS="-" read -r field1 field2 field3 field4 <<EOF |
114 | 114 | $1 |
115 | 115 | EOF |
116 | 116 | |
117 | 117 | # Separate into logical components for further validation |
118 | 118 | case $1 in |
119 | *-*-*-*-*) | |
120 | echo Invalid configuration \`"$1"\': more than four components >&2 | |
121 | exit 1 | |
122 | ;; | |
119 | 123 | *-*-*-*) |
120 | 124 | basic_machine=$field1-$field2 |
121 | os=-$field3-$field4 | |
125 | os=$field3-$field4 | |
122 | 126 | ;; |
123 | 127 | *-*-*) |
124 | 128 | # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two |
131 | 135 | | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ |
132 | 136 | | storm-chaos* | os2-emx* | rtmk-nova*) |
133 | 137 | basic_machine=$field1 |
134 | os=-$maybe_os | |
138 | os=$maybe_os | |
135 | 139 | ;; |
136 | 140 | android-linux) |
137 | 141 | basic_machine=$field1-unknown |
138 | os=-linux-android | |
142 | os=linux-android | |
139 | 143 | ;; |
140 | 144 | *) |
141 | 145 | basic_machine=$field1-$field2 |
142 | os=-$field3 | |
146 | os=$field3 | |
143 | 147 | ;; |
144 | 148 | esac |
145 | 149 | ;; |
146 | 150 | *-*) |
147 | basic_machine=$field1 | |
148 | os=-$field2 | |
151 | # A lone config we happen to match not fitting any patern | |
152 | case $field1-$field2 in | |
153 | decstation-3100) | |
154 | basic_machine=mips-dec | |
155 | os= | |
156 | ;; | |
157 | *-*) | |
158 | # Second component is usually, but not always the OS | |
159 | case $field2 in | |
160 | # Prevent following clause from handling this valid os | |
161 | sun*os*) | |
162 | basic_machine=$field1 | |
163 | os=$field2 | |
164 | ;; | |
165 | # Manufacturers | |
166 | dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ | |
167 | | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | |
168 | | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | |
169 | | convergent* | ncr* | news | 32* | 3600* | 3100* \ | |
170 | | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ | |
171 | | ultra | tti* | harris | dolphin | highlevel | gould \ | |
172 | | cbm | ns | masscomp | apple | axis | knuth | cray \ | |
173 | | microblaze* | sim | cisco \ | |
174 | | oki | wec | wrs | winbond) | |
175 | basic_machine=$field1-$field2 | |
176 | os= | |
177 | ;; | |
178 | *) | |
179 | basic_machine=$field1 | |
180 | os=$field2 | |
181 | ;; | |
182 | esac | |
183 | ;; | |
184 | esac | |
149 | 185 | ;; |
150 | 186 | *) |
151 | basic_machine=$1 | |
152 | os= | |
187 | # Convert single-component short-hands not valid as part of | |
188 | # multi-component configurations. | |
189 | case $field1 in | |
190 | 386bsd) | |
191 | basic_machine=i386-pc | |
192 | os=bsd | |
193 | ;; | |
194 | a29khif) | |
195 | basic_machine=a29k-amd | |
196 | os=udi | |
197 | ;; | |
198 | adobe68k) | |
199 | basic_machine=m68010-adobe | |
200 | os=scout | |
201 | ;; | |
202 | alliant) | |
203 | basic_machine=fx80-alliant | |
204 | os= | |
205 | ;; | |
206 | altos | altos3068) | |
207 | basic_machine=m68k-altos | |
208 | os= | |
209 | ;; | |
210 | am29k) | |
211 | basic_machine=a29k-none | |
212 | os=bsd | |
213 | ;; | |
214 | amdahl) | |
215 | basic_machine=580-amdahl | |
216 | os=sysv | |
217 | ;; | |
218 | amiga) | |
219 | basic_machine=m68k-unknown | |
220 | os= | |
221 | ;; | |
222 | amigaos | amigados) | |
223 | basic_machine=m68k-unknown | |
224 | os=amigaos | |
225 | ;; | |
226 | amigaunix | amix) | |
227 | basic_machine=m68k-unknown | |
228 | os=sysv4 | |
229 | ;; | |
230 | apollo68) | |
231 | basic_machine=m68k-apollo | |
232 | os=sysv | |
233 | ;; | |
234 | apollo68bsd) | |
235 | basic_machine=m68k-apollo | |
236 | os=bsd | |
237 | ;; | |
238 | aros) | |
239 | basic_machine=i386-pc | |
240 | os=aros | |
241 | ;; | |
242 | aux) | |
243 | basic_machine=m68k-apple | |
244 | os=aux | |
245 | ;; | |
246 | balance) | |
247 | basic_machine=ns32k-sequent | |
248 | os=dynix | |
249 | ;; | |
250 | blackfin) | |
251 | basic_machine=bfin-unknown | |
252 | os=linux | |
253 | ;; | |
254 | cegcc) | |
255 | basic_machine=arm-unknown | |
256 | os=cegcc | |
257 | ;; | |
258 | convex-c1) | |
259 | basic_machine=c1-convex | |
260 | os=bsd | |
261 | ;; | |
262 | convex-c2) | |
263 | basic_machine=c2-convex | |
264 | os=bsd | |
265 | ;; | |
266 | convex-c32) | |
267 | basic_machine=c32-convex | |
268 | os=bsd | |
269 | ;; | |
270 | convex-c34) | |
271 | basic_machine=c34-convex | |
272 | os=bsd | |
273 | ;; | |
274 | convex-c38) | |
275 | basic_machine=c38-convex | |
276 | os=bsd | |
277 | ;; | |
278 | cray) | |
279 | basic_machine=j90-cray | |
280 | os=unicos | |
281 | ;; | |
282 | crds | unos) | |
283 | basic_machine=m68k-crds | |
284 | os= | |
285 | ;; | |
286 | da30) | |
287 | basic_machine=m68k-da30 | |
288 | os= | |
289 | ;; | |
290 | decstation | pmax | pmin | dec3100 | decstatn) | |
291 | basic_machine=mips-dec | |
292 | os= | |
293 | ;; | |
294 | delta88) | |
295 | basic_machine=m88k-motorola | |
296 | os=sysv3 | |
297 | ;; | |
298 | dicos) | |
299 | basic_machine=i686-pc | |
300 | os=dicos | |
301 | ;; | |
302 | djgpp) | |
303 | basic_machine=i586-pc | |
304 | os=msdosdjgpp | |
305 | ;; | |
306 | ebmon29k) | |
307 | basic_machine=a29k-amd | |
308 | os=ebmon | |
309 | ;; | |
310 | es1800 | OSE68k | ose68k | ose | OSE) | |
311 | basic_machine=m68k-ericsson | |
312 | os=ose | |
313 | ;; | |
314 | gmicro) | |
315 | basic_machine=tron-gmicro | |
316 | os=sysv | |
317 | ;; | |
318 | go32) | |
319 | basic_machine=i386-pc | |
320 | os=go32 | |
321 | ;; | |
322 | h8300hms) | |
323 | basic_machine=h8300-hitachi | |
324 | os=hms | |
325 | ;; | |
326 | h8300xray) | |
327 | basic_machine=h8300-hitachi | |
328 | os=xray | |
329 | ;; | |
330 | h8500hms) | |
331 | basic_machine=h8500-hitachi | |
332 | os=hms | |
333 | ;; | |
334 | harris) | |
335 | basic_machine=m88k-harris | |
336 | os=sysv3 | |
337 | ;; | |
338 | hp300) | |
339 | basic_machine=m68k-hp | |
340 | ;; | |
341 | hp300bsd) | |
342 | basic_machine=m68k-hp | |
343 | os=bsd | |
344 | ;; | |
345 | hp300hpux) | |
346 | basic_machine=m68k-hp | |
347 | os=hpux | |
348 | ;; | |
349 | hppaosf) | |
350 | basic_machine=hppa1.1-hp | |
351 | os=osf | |
352 | ;; | |
353 | hppro) | |
354 | basic_machine=hppa1.1-hp | |
355 | os=proelf | |
356 | ;; | |
357 | i386mach) | |
358 | basic_machine=i386-mach | |
359 | os=mach | |
360 | ;; | |
361 | vsta) | |
362 | basic_machine=i386-pc | |
363 | os=vsta | |
364 | ;; | |
365 | isi68 | isi) | |
366 | basic_machine=m68k-isi | |
367 | os=sysv | |
368 | ;; | |
369 | m68knommu) | |
370 | basic_machine=m68k-unknown | |
371 | os=linux | |
372 | ;; | |
373 | magnum | m3230) | |
374 | basic_machine=mips-mips | |
375 | os=sysv | |
376 | ;; | |
377 | merlin) | |
378 | basic_machine=ns32k-utek | |
379 | os=sysv | |
380 | ;; | |
381 | mingw64) | |
382 | basic_machine=x86_64-pc | |
383 | os=mingw64 | |
384 | ;; | |
385 | mingw32) | |
386 | basic_machine=i686-pc | |
387 | os=mingw32 | |
388 | ;; | |
389 | mingw32ce) | |
390 | basic_machine=arm-unknown | |
391 | os=mingw32ce | |
392 | ;; | |
393 | monitor) | |
394 | basic_machine=m68k-rom68k | |
395 | os=coff | |
396 | ;; | |
397 | morphos) | |
398 | basic_machine=powerpc-unknown | |
399 | os=morphos | |
400 | ;; | |
401 | moxiebox) | |
402 | basic_machine=moxie-unknown | |
403 | os=moxiebox | |
404 | ;; | |
405 | msdos) | |
406 | basic_machine=i386-pc | |
407 | os=msdos | |
408 | ;; | |
409 | msys) | |
410 | basic_machine=i686-pc | |
411 | os=msys | |
412 | ;; | |
413 | mvs) | |
414 | basic_machine=i370-ibm | |
415 | os=mvs | |
416 | ;; | |
417 | nacl) | |
418 | basic_machine=le32-unknown | |
419 | os=nacl | |
420 | ;; | |
421 | ncr3000) | |
422 | basic_machine=i486-ncr | |
423 | os=sysv4 | |
424 | ;; | |
425 | netbsd386) | |
426 | basic_machine=i386-pc | |
427 | os=netbsd | |
428 | ;; | |
429 | netwinder) | |
430 | basic_machine=armv4l-rebel | |
431 | os=linux | |
432 | ;; | |
433 | news | news700 | news800 | news900) | |
434 | basic_machine=m68k-sony | |
435 | os=newsos | |
436 | ;; | |
437 | news1000) | |
438 | basic_machine=m68030-sony | |
439 | os=newsos | |
440 | ;; | |
441 | necv70) | |
442 | basic_machine=v70-nec | |
443 | os=sysv | |
444 | ;; | |
445 | nh3000) | |
446 | basic_machine=m68k-harris | |
447 | os=cxux | |
448 | ;; | |
449 | nh[45]000) | |
450 | basic_machine=m88k-harris | |
451 | os=cxux | |
452 | ;; | |
453 | nindy960) | |
454 | basic_machine=i960-intel | |
455 | os=nindy | |
456 | ;; | |
457 | mon960) | |
458 | basic_machine=i960-intel | |
459 | os=mon960 | |
460 | ;; | |
461 | nonstopux) | |
462 | basic_machine=mips-compaq | |
463 | os=nonstopux | |
464 | ;; | |
465 | os400) | |
466 | basic_machine=powerpc-ibm | |
467 | os=os400 | |
468 | ;; | |
469 | OSE68000 | ose68000) | |
470 | basic_machine=m68000-ericsson | |
471 | os=ose | |
472 | ;; | |
473 | os68k) | |
474 | basic_machine=m68k-none | |
475 | os=os68k | |
476 | ;; | |
477 | paragon) | |
478 | basic_machine=i860-intel | |
479 | os=osf | |
480 | ;; | |
481 | parisc) | |
482 | basic_machine=hppa-unknown | |
483 | os=linux | |
484 | ;; | |
485 | pw32) | |
486 | basic_machine=i586-unknown | |
487 | os=pw32 | |
488 | ;; | |
489 | rdos | rdos64) | |
490 | basic_machine=x86_64-pc | |
491 | os=rdos | |
492 | ;; | |
493 | rdos32) | |
494 | basic_machine=i386-pc | |
495 | os=rdos | |
496 | ;; | |
497 | rom68k) | |
498 | basic_machine=m68k-rom68k | |
499 | os=coff | |
500 | ;; | |
501 | sa29200) | |
502 | basic_machine=a29k-amd | |
503 | os=udi | |
504 | ;; | |
505 | sei) | |
506 | basic_machine=mips-sei | |
507 | os=seiux | |
508 | ;; | |
509 | sequent) | |
510 | basic_machine=i386-sequent | |
511 | os= | |
512 | ;; | |
513 | sps7) | |
514 | basic_machine=m68k-bull | |
515 | os=sysv2 | |
516 | ;; | |
517 | st2000) | |
518 | basic_machine=m68k-tandem | |
519 | os= | |
520 | ;; | |
521 | stratus) | |
522 | basic_machine=i860-stratus | |
523 | os=sysv4 | |
524 | ;; | |
525 | sun2) | |
526 | basic_machine=m68000-sun | |
527 | os= | |
528 | ;; | |
529 | sun2os3) | |
530 | basic_machine=m68000-sun | |
531 | os=sunos3 | |
532 | ;; | |
533 | sun2os4) | |
534 | basic_machine=m68000-sun | |
535 | os=sunos4 | |
536 | ;; | |
537 | sun3) | |
538 | basic_machine=m68k-sun | |
539 | os= | |
540 | ;; | |
541 | sun3os3) | |
542 | basic_machine=m68k-sun | |
543 | os=sunos3 | |
544 | ;; | |
545 | sun3os4) | |
546 | basic_machine=m68k-sun | |
547 | os=sunos4 | |
548 | ;; | |
549 | sun4) | |
550 | basic_machine=sparc-sun | |
551 | os= | |
552 | ;; | |
553 | sun4os3) | |
554 | basic_machine=sparc-sun | |
555 | os=sunos3 | |
556 | ;; | |
557 | sun4os4) | |
558 | basic_machine=sparc-sun | |
559 | os=sunos4 | |
560 | ;; | |
561 | sun4sol2) | |
562 | basic_machine=sparc-sun | |
563 | os=solaris2 | |
564 | ;; | |
565 | sun386 | sun386i | roadrunner) | |
566 | basic_machine=i386-sun | |
567 | os= | |
568 | ;; | |
569 | sv1) | |
570 | basic_machine=sv1-cray | |
571 | os=unicos | |
572 | ;; | |
573 | symmetry) | |
574 | basic_machine=i386-sequent | |
575 | os=dynix | |
576 | ;; | |
577 | t3e) | |
578 | basic_machine=alphaev5-cray | |
579 | os=unicos | |
580 | ;; | |
581 | t90) | |
582 | basic_machine=t90-cray | |
583 | os=unicos | |
584 | ;; | |
585 | toad1) | |
586 | basic_machine=pdp10-xkl | |
587 | os=tops20 | |
588 | ;; | |
589 | tpf) | |
590 | basic_machine=s390x-ibm | |
591 | os=tpf | |
592 | ;; | |
593 | udi29k) | |
594 | basic_machine=a29k-amd | |
595 | os=udi | |
596 | ;; | |
597 | ultra3) | |
598 | basic_machine=a29k-nyu | |
599 | os=sym1 | |
600 | ;; | |
601 | v810 | necv810) | |
602 | basic_machine=v810-nec | |
603 | os=none | |
604 | ;; | |
605 | vaxv) | |
606 | basic_machine=vax-dec | |
607 | os=sysv | |
608 | ;; | |
609 | vms) | |
610 | basic_machine=vax-dec | |
611 | os=vms | |
612 | ;; | |
613 | vxworks960) | |
614 | basic_machine=i960-wrs | |
615 | os=vxworks | |
616 | ;; | |
617 | vxworks68) | |
618 | basic_machine=m68k-wrs | |
619 | os=vxworks | |
620 | ;; | |
621 | vxworks29k) | |
622 | basic_machine=a29k-wrs | |
623 | os=vxworks | |
624 | ;; | |
625 | xbox) | |
626 | basic_machine=i686-pc | |
627 | os=mingw32 | |
628 | ;; | |
629 | ymp) | |
630 | basic_machine=ymp-cray | |
631 | os=unicos | |
632 | ;; | |
633 | *) | |
634 | basic_machine=$1 | |
635 | os= | |
636 | ;; | |
637 | esac | |
153 | 638 | ;; |
154 | 639 | esac |
155 | 640 | |
156 | ### Let's recognize common machines as not being operating systems so | |
157 | ### that things like config.sub decstation-3100 work. We also | |
158 | ### recognize some manufacturers as not being operating systems, so we | |
159 | ### can provide default operating systems below. | |
160 | case $os in | |
161 | -sun*os*) | |
162 | # Prevent following clause from handling this invalid input. | |
163 | ;; | |
164 | -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ | |
165 | -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ | |
166 | -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ | |
167 | -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ | |
168 | -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ | |
169 | -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ | |
170 | -apple | -axis | -knuth | -cray | -microblaze*) | |
171 | os= | |
172 | basic_machine=$1 | |
173 | ;; | |
174 | -bluegene*) | |
175 | os=-cnk | |
176 | ;; | |
177 | -sim | -cisco | -oki | -wec | -winbond) | |
178 | os= | |
179 | basic_machine=$1 | |
180 | ;; | |
181 | -scout) | |
182 | ;; | |
183 | -wrs) | |
184 | os=-vxworks | |
185 | basic_machine=$1 | |
186 | ;; | |
187 | -chorusos*) | |
188 | os=-chorusos | |
189 | basic_machine=$1 | |
190 | ;; | |
191 | -chorusrdb) | |
192 | os=-chorusrdb | |
193 | basic_machine=$1 | |
194 | ;; | |
195 | -hiux*) | |
196 | os=-hiuxwe2 | |
197 | ;; | |
198 | -sco6) | |
199 | os=-sco5v6 | |
200 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` | |
201 | ;; | |
202 | -sco5) | |
203 | os=-sco3.2v5 | |
204 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` | |
205 | ;; | |
206 | -sco4) | |
207 | os=-sco3.2v4 | |
208 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` | |
209 | ;; | |
210 | -sco3.2.[4-9]*) | |
211 | os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` | |
212 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` | |
213 | ;; | |
214 | -sco3.2v[4-9]*) | |
215 | # Don't forget version if it is 3.2v4 or newer. | |
216 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` | |
217 | ;; | |
218 | -sco5v6*) | |
219 | # Don't forget version if it is 3.2v4 or newer. | |
220 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` | |
221 | ;; | |
222 | -sco*) | |
223 | os=-sco3.2v2 | |
224 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` | |
225 | ;; | |
226 | -udk*) | |
227 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` | |
228 | ;; | |
229 | -isc) | |
230 | os=-isc2.2 | |
231 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` | |
232 | ;; | |
233 | -clix*) | |
234 | basic_machine=clipper-intergraph | |
235 | ;; | |
236 | -isc*) | |
237 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` | |
238 | ;; | |
239 | -lynx*178) | |
240 | os=-lynxos178 | |
241 | ;; | |
242 | -lynx*5) | |
243 | os=-lynxos5 | |
244 | ;; | |
245 | -lynx*) | |
246 | os=-lynxos | |
247 | ;; | |
248 | -ptx*) | |
249 | basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` | |
250 | ;; | |
251 | -psos*) | |
252 | os=-psos | |
253 | ;; | |
254 | -mint | -mint[0-9]*) | |
255 | basic_machine=m68k-atari | |
256 | os=-mint | |
257 | ;; | |
258 | esac | |
259 | ||
260 | # Decode aliases for certain CPU-COMPANY combinations. | |
641 | # Decode 1-component or ad-hoc basic machines | |
261 | 642 | case $basic_machine in |
262 | # Recognize the basic CPU types without company name. | |
263 | # Some are omitted here because they have special meanings below. | |
264 | 1750a | 580 \ | |
265 | | a29k \ | |
266 | | aarch64 | aarch64_be \ | |
267 | | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | |
268 | | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | |
269 | | am33_2.0 \ | |
270 | | arc | arceb \ | |
271 | | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv6m | armv[78][arm] \ | |
272 | | avr | avr32 \ | |
273 | | ba \ | |
274 | | be32 | be64 \ | |
275 | | bfin \ | |
276 | | c4x | c8051 | clipper | csky \ | |
277 | | d10v | d30v | dlx | dsp16xx \ | |
278 | | e2k | epiphany \ | |
279 | | fido | fr30 | frv | ft32 \ | |
280 | | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | |
281 | | hexagon \ | |
282 | | i370 | i860 | i960 | ia16 | ia64 \ | |
283 | | ip2k | iq2000 \ | |
284 | | k1om \ | |
285 | | le32 | le64 \ | |
286 | | lm32 \ | |
287 | | m32c | m32r | m32rle | m68000 | m68k | m88k \ | |
288 | | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | |
289 | | mips | mipsbe | mipseb | mipsel | mipsle \ | |
290 | | mips16 \ | |
291 | | mips64 | mips64el \ | |
292 | | mips64octeon | mips64octeonel \ | |
293 | | mips64orion | mips64orionel \ | |
294 | | mips64r5900 | mips64r5900el \ | |
295 | | mips64vr | mips64vrel \ | |
296 | | mips64vr4100 | mips64vr4100el \ | |
297 | | mips64vr4300 | mips64vr4300el \ | |
298 | | mips64vr5000 | mips64vr5000el \ | |
299 | | mips64vr5900 | mips64vr5900el \ | |
300 | | mipsisa32 | mipsisa32el \ | |
301 | | mipsisa32r2 | mipsisa32r2el \ | |
302 | | mipsisa32r6 | mipsisa32r6el \ | |
303 | | mipsisa64 | mipsisa64el \ | |
304 | | mipsisa64r2 | mipsisa64r2el \ | |
305 | | mipsisa64r6 | mipsisa64r6el \ | |
306 | | mipsisa64sb1 | mipsisa64sb1el \ | |
307 | | mipsisa64sr71k | mipsisa64sr71kel \ | |
308 | | mipsr5900 | mipsr5900el \ | |
309 | | mipstx39 | mipstx39el \ | |
310 | | mn10200 | mn10300 \ | |
311 | | moxie \ | |
312 | | mt \ | |
313 | | msp430 \ | |
314 | | nds32 | nds32le | nds32be \ | |
315 | | nfp \ | |
316 | | nios | nios2 | nios2eb | nios2el \ | |
317 | | ns16k | ns32k \ | |
318 | | open8 | or1k | or1knd | or32 \ | |
319 | | pdp10 | pj | pjl \ | |
320 | | powerpc | powerpc64 | powerpc64le | powerpcle \ | |
321 | | pru \ | |
322 | | pyramid \ | |
323 | | riscv32 | riscv64 \ | |
324 | | rl78 | rx \ | |
325 | | score \ | |
326 | | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | |
327 | | sh64 | sh64le \ | |
328 | | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | |
329 | | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | |
330 | | spu \ | |
331 | | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | |
332 | | ubicom32 \ | |
333 | | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | |
334 | | visium \ | |
335 | | wasm32 \ | |
336 | | x86 | xc16x | xstormy16 | xtensa \ | |
337 | | z8k | z80) | |
338 | basic_machine=$basic_machine-unknown | |
339 | ;; | |
340 | c54x) | |
341 | basic_machine=tic54x-unknown | |
342 | ;; | |
343 | c55x) | |
344 | basic_machine=tic55x-unknown | |
345 | ;; | |
346 | c6x) | |
347 | basic_machine=tic6x-unknown | |
643 | # Here we handle the default manufacturer of certain CPU types. It is in | |
644 | # some cases the only manufacturer, in others, it is the most popular. | |
645 | w89k) | |
646 | cpu=hppa1.1 | |
647 | vendor=winbond | |
648 | ;; | |
649 | op50n) | |
650 | cpu=hppa1.1 | |
651 | vendor=oki | |
652 | ;; | |
653 | op60c) | |
654 | cpu=hppa1.1 | |
655 | vendor=oki | |
656 | ;; | |
657 | ibm*) | |
658 | cpu=i370 | |
659 | vendor=ibm | |
660 | ;; | |
661 | orion105) | |
662 | cpu=clipper | |
663 | vendor=highlevel | |
664 | ;; | |
665 | mac | mpw | mac-mpw) | |
666 | cpu=m68k | |
667 | vendor=apple | |
668 | ;; | |
669 | pmac | pmac-mpw) | |
670 | cpu=powerpc | |
671 | vendor=apple | |
672 | ;; | |
673 | ||
674 | # Recognize the various machine names and aliases which stand | |
675 | # for a CPU type and a company and sometimes even an OS. | |
676 | 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) | |
677 | cpu=m68000 | |
678 | vendor=att | |
679 | ;; | |
680 | 3b*) | |
681 | cpu=we32k | |
682 | vendor=att | |
683 | ;; | |
684 | bluegene*) | |
685 | cpu=powerpc | |
686 | vendor=ibm | |
687 | os=cnk | |
688 | ;; | |
689 | decsystem10* | dec10*) | |
690 | cpu=pdp10 | |
691 | vendor=dec | |
692 | os=tops10 | |
693 | ;; | |
694 | decsystem20* | dec20*) | |
695 | cpu=pdp10 | |
696 | vendor=dec | |
697 | os=tops20 | |
698 | ;; | |
699 | delta | 3300 | motorola-3300 | motorola-delta \ | |
700 | | 3300-motorola | delta-motorola) | |
701 | cpu=m68k | |
702 | vendor=motorola | |
703 | ;; | |
704 | dpx2*) | |
705 | cpu=m68k | |
706 | vendor=bull | |
707 | os=sysv3 | |
708 | ;; | |
709 | encore | umax | mmax) | |
710 | cpu=ns32k | |
711 | vendor=encore | |
712 | ;; | |
713 | elxsi) | |
714 | cpu=elxsi | |
715 | vendor=elxsi | |
716 | os=${os:-bsd} | |
717 | ;; | |
718 | fx2800) | |
719 | cpu=i860 | |
720 | vendor=alliant | |
721 | ;; | |
722 | genix) | |
723 | cpu=ns32k | |
724 | vendor=ns | |
725 | ;; | |
726 | h3050r* | hiux*) | |
727 | cpu=hppa1.1 | |
728 | vendor=hitachi | |
729 | os=hiuxwe2 | |
730 | ;; | |
731 | hp3k9[0-9][0-9] | hp9[0-9][0-9]) | |
732 | cpu=hppa1.0 | |
733 | vendor=hp | |
734 | ;; | |
735 | hp9k2[0-9][0-9] | hp9k31[0-9]) | |
736 | cpu=m68000 | |
737 | vendor=hp | |
738 | ;; | |
739 | hp9k3[2-9][0-9]) | |
740 | cpu=m68k | |
741 | vendor=hp | |
742 | ;; | |
743 | hp9k6[0-9][0-9] | hp6[0-9][0-9]) | |
744 | cpu=hppa1.0 | |
745 | vendor=hp | |
746 | ;; | |
747 | hp9k7[0-79][0-9] | hp7[0-79][0-9]) | |
748 | cpu=hppa1.1 | |
749 | vendor=hp | |
750 | ;; | |
751 | hp9k78[0-9] | hp78[0-9]) | |
752 | # FIXME: really hppa2.0-hp | |
753 | cpu=hppa1.1 | |
754 | vendor=hp | |
755 | ;; | |
756 | hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) | |
757 | # FIXME: really hppa2.0-hp | |
758 | cpu=hppa1.1 | |
759 | vendor=hp | |
760 | ;; | |
761 | hp9k8[0-9][13679] | hp8[0-9][13679]) | |
762 | cpu=hppa1.1 | |
763 | vendor=hp | |
764 | ;; | |
765 | hp9k8[0-9][0-9] | hp8[0-9][0-9]) | |
766 | cpu=hppa1.0 | |
767 | vendor=hp | |
768 | ;; | |
769 | i*86v32) | |
770 | cpu=`echo "$1" | sed -e 's/86.*/86/'` | |
771 | vendor=pc | |
772 | os=sysv32 | |
773 | ;; | |
774 | i*86v4*) | |
775 | cpu=`echo "$1" | sed -e 's/86.*/86/'` | |
776 | vendor=pc | |
777 | os=sysv4 | |
778 | ;; | |
779 | i*86v) | |
780 | cpu=`echo "$1" | sed -e 's/86.*/86/'` | |
781 | vendor=pc | |
782 | os=sysv | |
783 | ;; | |
784 | i*86sol2) | |
785 | cpu=`echo "$1" | sed -e 's/86.*/86/'` | |
786 | vendor=pc | |
787 | os=solaris2 | |
788 | ;; | |
789 | j90 | j90-cray) | |
790 | cpu=j90 | |
791 | vendor=cray | |
792 | os=${os:-unicos} | |
793 | ;; | |
794 | iris | iris4d) | |
795 | cpu=mips | |
796 | vendor=sgi | |
797 | case $os in | |
798 | irix*) | |
799 | ;; | |
800 | *) | |
801 | os=irix4 | |
802 | ;; | |
803 | esac | |
804 | ;; | |
805 | miniframe) | |
806 | cpu=m68000 | |
807 | vendor=convergent | |
808 | ;; | |
809 | *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) | |
810 | cpu=m68k | |
811 | vendor=atari | |
812 | os=mint | |
813 | ;; | |
814 | news-3600 | risc-news) | |
815 | cpu=mips | |
816 | vendor=sony | |
817 | os=newsos | |
818 | ;; | |
819 | next | m*-next) | |
820 | cpu=m68k | |
821 | vendor=next | |
822 | case $os in | |
823 | nextstep* ) | |
824 | ;; | |
825 | ns2*) | |
826 | os=nextstep2 | |
827 | ;; | |
828 | *) | |
829 | os=nextstep3 | |
830 | ;; | |
831 | esac | |
832 | ;; | |
833 | np1) | |
834 | cpu=np1 | |
835 | vendor=gould | |
836 | ;; | |
837 | op50n-* | op60c-*) | |
838 | cpu=hppa1.1 | |
839 | vendor=oki | |
840 | os=proelf | |
841 | ;; | |
842 | pa-hitachi) | |
843 | cpu=hppa1.1 | |
844 | vendor=hitachi | |
845 | os=hiuxwe2 | |
846 | ;; | |
847 | pbd) | |
848 | cpu=sparc | |
849 | vendor=tti | |
850 | ;; | |
851 | pbb) | |
852 | cpu=m68k | |
853 | vendor=tti | |
854 | ;; | |
855 | pc532) | |
856 | cpu=ns32k | |
857 | vendor=pc532 | |
858 | ;; | |
859 | pn) | |
860 | cpu=pn | |
861 | vendor=gould | |
862 | ;; | |
863 | power) | |
864 | cpu=power | |
865 | vendor=ibm | |
866 | ;; | |
867 | ps2) | |
868 | cpu=i386 | |
869 | vendor=ibm | |
870 | ;; | |
871 | rm[46]00) | |
872 | cpu=mips | |
873 | vendor=siemens | |
874 | ;; | |
875 | rtpc | rtpc-*) | |
876 | cpu=romp | |
877 | vendor=ibm | |
878 | ;; | |
879 | sde) | |
880 | cpu=mipsisa32 | |
881 | vendor=sde | |
882 | os=${os:-elf} | |
883 | ;; | |
884 | simso-wrs) | |
885 | cpu=sparclite | |
886 | vendor=wrs | |
887 | os=vxworks | |
888 | ;; | |
889 | tower | tower-32) | |
890 | cpu=m68k | |
891 | vendor=ncr | |
892 | ;; | |
893 | vpp*|vx|vx-*) | |
894 | cpu=f301 | |
895 | vendor=fujitsu | |
896 | ;; | |
897 | w65) | |
898 | cpu=w65 | |
899 | vendor=wdc | |
900 | ;; | |
901 | w89k-*) | |
902 | cpu=hppa1.1 | |
903 | vendor=winbond | |
904 | os=proelf | |
905 | ;; | |
906 | none) | |
907 | cpu=none | |
908 | vendor=none | |
348 | 909 | ;; |
349 | 910 | leon|leon[3-9]) |
350 | basic_machine=sparc-$basic_machine | |
351 | ;; | |
352 | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) | |
353 | basic_machine=$basic_machine-unknown | |
354 | os=-none | |
355 | ;; | |
356 | m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) | |
357 | ;; | |
358 | m9s12z | m68hcs12z | hcs12z | s12z) | |
359 | basic_machine=s12z-unknown | |
360 | os=-none | |
361 | ;; | |
362 | ms1) | |
363 | basic_machine=mt-unknown | |
364 | ;; | |
365 | ||
366 | strongarm | thumb | xscale) | |
367 | basic_machine=arm-unknown | |
368 | ;; | |
369 | xgate) | |
370 | basic_machine=$basic_machine-unknown | |
371 | os=-none | |
372 | ;; | |
373 | xscaleeb) | |
374 | basic_machine=armeb-unknown | |
375 | ;; | |
376 | ||
377 | xscaleel) | |
378 | basic_machine=armel-unknown | |
379 | ;; | |
380 | ||
911 | cpu=sparc | |
912 | vendor=$basic_machine | |
913 | ;; | |
914 | leon-*|leon[3-9]-*) | |
915 | cpu=sparc | |
916 | vendor=`echo "$basic_machine" | sed 's/-.*//'` | |
917 | ;; | |
918 | ||
919 | *-*) | |
920 | IFS="-" read -r cpu vendor <<EOF | |
921 | $basic_machine | |
922 | EOF | |
923 | ;; | |
381 | 924 | # We use `pc' rather than `unknown' |
382 | 925 | # because (1) that's what they normally are, and |
383 | 926 | # (2) the word "unknown" tends to confuse beginning users. |
384 | 927 | i*86 | x86_64) |
385 | basic_machine=$basic_machine-pc | |
386 | ;; | |
387 | # Object if more than one company name word. | |
388 | *-*-*) | |
389 | echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 | |
390 | exit 1 | |
391 | ;; | |
392 | # Recognize the basic CPU types with company name. | |
393 | 580-* \ | |
394 | | a29k-* \ | |
395 | | aarch64-* | aarch64_be-* \ | |
396 | | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | |
397 | | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | |
398 | | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | |
399 | | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | |
400 | | avr-* | avr32-* \ | |
401 | | ba-* \ | |
402 | | be32-* | be64-* \ | |
403 | | bfin-* | bs2000-* \ | |
404 | | c[123]* | c30-* | [cjt]90-* | c4x-* \ | |
405 | | c8051-* | clipper-* | craynv-* | csky-* | cydra-* \ | |
406 | | d10v-* | d30v-* | dlx-* \ | |
407 | | e2k-* | elxsi-* \ | |
408 | | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | |
409 | | h8300-* | h8500-* \ | |
410 | | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | |
411 | | hexagon-* \ | |
412 | | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | |
413 | | ip2k-* | iq2000-* \ | |
414 | | k1om-* \ | |
415 | | le32-* | le64-* \ | |
416 | | lm32-* \ | |
417 | | m32c-* | m32r-* | m32rle-* \ | |
418 | | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | |
419 | | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | |
420 | | microblaze-* | microblazeel-* \ | |
421 | | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | |
422 | | mips16-* \ | |
423 | | mips64-* | mips64el-* \ | |
424 | | mips64octeon-* | mips64octeonel-* \ | |
425 | | mips64orion-* | mips64orionel-* \ | |
426 | | mips64r5900-* | mips64r5900el-* \ | |
427 | | mips64vr-* | mips64vrel-* \ | |
428 | | mips64vr4100-* | mips64vr4100el-* \ | |
429 | | mips64vr4300-* | mips64vr4300el-* \ | |
430 | | mips64vr5000-* | mips64vr5000el-* \ | |
431 | | mips64vr5900-* | mips64vr5900el-* \ | |
432 | | mipsisa32-* | mipsisa32el-* \ | |
433 | | mipsisa32r2-* | mipsisa32r2el-* \ | |
434 | | mipsisa32r6-* | mipsisa32r6el-* \ | |
435 | | mipsisa64-* | mipsisa64el-* \ | |
436 | | mipsisa64r2-* | mipsisa64r2el-* \ | |
437 | | mipsisa64r6-* | mipsisa64r6el-* \ | |
438 | | mipsisa64sb1-* | mipsisa64sb1el-* \ | |
439 | | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | |
440 | | mipsr5900-* | mipsr5900el-* \ | |
441 | | mipstx39-* | mipstx39el-* \ | |
442 | | mmix-* \ | |
443 | | mt-* \ | |
444 | | msp430-* \ | |
445 | | nds32-* | nds32le-* | nds32be-* \ | |
446 | | nfp-* \ | |
447 | | nios-* | nios2-* | nios2eb-* | nios2el-* \ | |
448 | | none-* | np1-* | ns16k-* | ns32k-* \ | |
449 | | open8-* \ | |
450 | | or1k*-* \ | |
451 | | orion-* \ | |
452 | | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | |
453 | | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | |
454 | | pru-* \ | |
455 | | pyramid-* \ | |
456 | | riscv32-* | riscv64-* \ | |
457 | | rl78-* | romp-* | rs6000-* | rx-* \ | |
458 | | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | |
459 | | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | |
460 | | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | |
461 | | sparclite-* \ | |
462 | | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | |
463 | | tahoe-* \ | |
464 | | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | |
465 | | tile*-* \ | |
466 | | tron-* \ | |
467 | | ubicom32-* \ | |
468 | | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | |
469 | | vax-* \ | |
470 | | visium-* \ | |
471 | | wasm32-* \ | |
472 | | we32k-* \ | |
473 | | x86-* | x86_64-* | xc16x-* | xps100-* \ | |
474 | | xstormy16-* | xtensa*-* \ | |
475 | | ymp-* \ | |
476 | | z8k-* | z80-*) | |
477 | ;; | |
478 | # Recognize the basic CPU types without company name, with glob match. | |
479 | xtensa*) | |
480 | basic_machine=$basic_machine-unknown | |
481 | ;; | |
482 | # Recognize the various machine names and aliases which stand | |
483 | # for a CPU type and a company and sometimes even an OS. | |
484 | 386bsd) | |
485 | basic_machine=i386-pc | |
486 | os=-bsd | |
487 | ;; | |
488 | 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) | |
489 | basic_machine=m68000-att | |
490 | ;; | |
491 | 3b*) | |
492 | basic_machine=we32k-att | |
493 | ;; | |
494 | a29khif) | |
495 | basic_machine=a29k-amd | |
496 | os=-udi | |
497 | ;; | |
498 | abacus) | |
499 | basic_machine=abacus-unknown | |
500 | ;; | |
501 | adobe68k) | |
502 | basic_machine=m68010-adobe | |
503 | os=-scout | |
504 | ;; | |
505 | alliant | fx80) | |
506 | basic_machine=fx80-alliant | |
507 | ;; | |
508 | altos | altos3068) | |
509 | basic_machine=m68k-altos | |
510 | ;; | |
511 | am29k) | |
512 | basic_machine=a29k-none | |
513 | os=-bsd | |
514 | ;; | |
515 | amd64) | |
516 | basic_machine=x86_64-pc | |
517 | ;; | |
928 | cpu=$basic_machine | |
929 | vendor=pc | |
930 | ;; | |
931 | # These rules are duplicated from below for sake of the special case above; | |
932 | # i.e. things that normalized to x86 arches should also default to "pc" | |
933 | pc98) | |
934 | cpu=i386 | |
935 | vendor=pc | |
936 | ;; | |
937 | x64 | amd64) | |
938 | cpu=x86_64 | |
939 | vendor=pc | |
940 | ;; | |
941 | # Recognize the basic CPU types without company name. | |
942 | *) | |
943 | cpu=$basic_machine | |
944 | vendor=unknown | |
945 | ;; | |
946 | esac | |
947 | ||
948 | unset -v basic_machine | |
949 | ||
950 | # Decode basic machines in the full and proper CPU-Company form. | |
951 | case $cpu-$vendor in | |
952 | # Here we handle the default manufacturer of certain CPU types in cannonical form. It is in | |
953 | # some cases the only manufacturer, in others, it is the most popular. | |
954 | craynv-unknown) | |
955 | vendor=cray | |
956 | os=${os:-unicosmp} | |
957 | ;; | |
958 | c90-unknown | c90-cray) | |
959 | vendor=cray | |
960 | os=${os:-unicos} | |
961 | ;; | |
962 | fx80-unknown) | |
963 | vendor=alliant | |
964 | ;; | |
965 | romp-unknown) | |
966 | vendor=ibm | |
967 | ;; | |
968 | mmix-unknown) | |
969 | vendor=knuth | |
970 | ;; | |
971 | microblaze-unknown | microblazeel-unknown) | |
972 | vendor=xilinx | |
973 | ;; | |
974 | rs6000-unknown) | |
975 | vendor=ibm | |
976 | ;; | |
977 | vax-unknown) | |
978 | vendor=dec | |
979 | ;; | |
980 | pdp11-unknown) | |
981 | vendor=dec | |
982 | ;; | |
983 | we32k-unknown) | |
984 | vendor=att | |
985 | ;; | |
986 | cydra-unknown) | |
987 | vendor=cydrome | |
988 | ;; | |
989 | i370-ibm*) | |
990 | vendor=ibm | |
991 | ;; | |
992 | orion-unknown) | |
993 | vendor=highlevel | |
994 | ;; | |
995 | xps-unknown | xps100-unknown) | |
996 | cpu=xps100 | |
997 | vendor=honeywell | |
998 | ;; | |
999 | ||
1000 | # Here we normalize CPU types with a missing or matching vendor | |
1001 | dpx20-unknown | dpx20-bull) | |
1002 | cpu=rs6000 | |
1003 | vendor=bull | |
1004 | os=${os:-bosx} | |
1005 | ;; | |
1006 | ||
1007 | # Here we normalize CPU types irrespective of the vendor | |
518 | 1008 | amd64-*) |
519 | basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
520 | ;; | |
521 | amdahl) | |
522 | basic_machine=580-amdahl | |
523 | os=-sysv | |
524 | ;; | |
525 | amiga | amiga-*) | |
526 | basic_machine=m68k-unknown | |
527 | ;; | |
528 | amigaos | amigados) | |
529 | basic_machine=m68k-unknown | |
530 | os=-amigaos | |
531 | ;; | |
532 | amigaunix | amix) | |
533 | basic_machine=m68k-unknown | |
534 | os=-sysv4 | |
535 | ;; | |
536 | apollo68) | |
537 | basic_machine=m68k-apollo | |
538 | os=-sysv | |
539 | ;; | |
540 | apollo68bsd) | |
541 | basic_machine=m68k-apollo | |
542 | os=-bsd | |
543 | ;; | |
544 | aros) | |
545 | basic_machine=i386-pc | |
546 | os=-aros | |
547 | ;; | |
548 | asmjs) | |
549 | basic_machine=asmjs-unknown | |
550 | ;; | |
551 | aux) | |
552 | basic_machine=m68k-apple | |
553 | os=-aux | |
554 | ;; | |
555 | balance) | |
556 | basic_machine=ns32k-sequent | |
557 | os=-dynix | |
558 | ;; | |
559 | blackfin) | |
560 | basic_machine=bfin-unknown | |
561 | os=-linux | |
1009 | cpu=x86_64 | |
562 | 1010 | ;; |
563 | 1011 | blackfin-*) |
564 | basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
565 | os=-linux | |
566 | ;; | |
567 | bluegene*) | |
568 | basic_machine=powerpc-ibm | |
569 | os=-cnk | |
1012 | cpu=bfin | |
1013 | os=linux | |
570 | 1014 | ;; |
571 | 1015 | c54x-*) |
572 | basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1016 | cpu=tic54x | |
573 | 1017 | ;; |
574 | 1018 | c55x-*) |
575 | basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1019 | cpu=tic55x | |
576 | 1020 | ;; |
577 | 1021 | c6x-*) |
578 | basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
579 | ;; | |
580 | c90) | |
581 | basic_machine=c90-cray | |
582 | os=-unicos | |
583 | ;; | |
584 | cegcc) | |
585 | basic_machine=arm-unknown | |
586 | os=-cegcc | |
587 | ;; | |
588 | convex-c1) | |
589 | basic_machine=c1-convex | |
590 | os=-bsd | |
591 | ;; | |
592 | convex-c2) | |
593 | basic_machine=c2-convex | |
594 | os=-bsd | |
595 | ;; | |
596 | convex-c32) | |
597 | basic_machine=c32-convex | |
598 | os=-bsd | |
599 | ;; | |
600 | convex-c34) | |
601 | basic_machine=c34-convex | |
602 | os=-bsd | |
603 | ;; | |
604 | convex-c38) | |
605 | basic_machine=c38-convex | |
606 | os=-bsd | |
607 | ;; | |
608 | cray | j90) | |
609 | basic_machine=j90-cray | |
610 | os=-unicos | |
611 | ;; | |
612 | craynv) | |
613 | basic_machine=craynv-cray | |
614 | os=-unicosmp | |
615 | ;; | |
616 | cr16 | cr16-*) | |
617 | basic_machine=cr16-unknown | |
618 | os=-elf | |
619 | ;; | |
620 | crds | unos) | |
621 | basic_machine=m68k-crds | |
622 | ;; | |
623 | crisv32 | crisv32-* | etraxfs*) | |
624 | basic_machine=crisv32-axis | |
625 | ;; | |
626 | cris | cris-* | etrax*) | |
627 | basic_machine=cris-axis | |
628 | ;; | |
629 | crx) | |
630 | basic_machine=crx-unknown | |
631 | os=-elf | |
632 | ;; | |
633 | da30 | da30-*) | |
634 | basic_machine=m68k-da30 | |
635 | ;; | |
636 | decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) | |
637 | basic_machine=mips-dec | |
638 | ;; | |
639 | decsystem10* | dec10*) | |
640 | basic_machine=pdp10-dec | |
641 | os=-tops10 | |
642 | ;; | |
643 | decsystem20* | dec20*) | |
644 | basic_machine=pdp10-dec | |
645 | os=-tops20 | |
646 | ;; | |
647 | delta | 3300 | motorola-3300 | motorola-delta \ | |
648 | | 3300-motorola | delta-motorola) | |
649 | basic_machine=m68k-motorola | |
650 | ;; | |
651 | delta88) | |
652 | basic_machine=m88k-motorola | |
653 | os=-sysv3 | |
654 | ;; | |
655 | dicos) | |
656 | basic_machine=i686-pc | |
657 | os=-dicos | |
658 | ;; | |
659 | djgpp) | |
660 | basic_machine=i586-pc | |
661 | os=-msdosdjgpp | |
662 | ;; | |
663 | dpx20 | dpx20-*) | |
664 | basic_machine=rs6000-bull | |
665 | os=-bosx | |
666 | ;; | |
667 | dpx2*) | |
668 | basic_machine=m68k-bull | |
669 | os=-sysv3 | |
670 | ;; | |
671 | e500v[12]) | |
672 | basic_machine=powerpc-unknown | |
1022 | cpu=tic6x | |
1023 | ;; | |
1024 | e500v[12]-*) | |
1025 | cpu=powerpc | |
673 | 1026 | os=$os"spe" |
674 | 1027 | ;; |
675 | e500v[12]-*) | |
676 | basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
677 | os=$os"spe" | |
678 | ;; | |
679 | ebmon29k) | |
680 | basic_machine=a29k-amd | |
681 | os=-ebmon | |
682 | ;; | |
683 | elxsi) | |
684 | basic_machine=elxsi-elxsi | |
685 | os=-bsd | |
686 | ;; | |
687 | encore | umax | mmax) | |
688 | basic_machine=ns32k-encore | |
689 | ;; | |
690 | es1800 | OSE68k | ose68k | ose | OSE) | |
691 | basic_machine=m68k-ericsson | |
692 | os=-ose | |
693 | ;; | |
694 | fx2800) | |
695 | basic_machine=i860-alliant | |
696 | ;; | |
697 | genix) | |
698 | basic_machine=ns32k-ns | |
699 | ;; | |
700 | gmicro) | |
701 | basic_machine=tron-gmicro | |
702 | os=-sysv | |
703 | ;; | |
704 | go32) | |
705 | basic_machine=i386-pc | |
706 | os=-go32 | |
707 | ;; | |
708 | h3050r* | hiux*) | |
709 | basic_machine=hppa1.1-hitachi | |
710 | os=-hiuxwe2 | |
711 | ;; | |
712 | h8300hms) | |
713 | basic_machine=h8300-hitachi | |
714 | os=-hms | |
715 | ;; | |
716 | h8300xray) | |
717 | basic_machine=h8300-hitachi | |
718 | os=-xray | |
719 | ;; | |
720 | h8500hms) | |
721 | basic_machine=h8500-hitachi | |
722 | os=-hms | |
723 | ;; | |
724 | harris) | |
725 | basic_machine=m88k-harris | |
726 | os=-sysv3 | |
727 | ;; | |
728 | hp300-*) | |
729 | basic_machine=m68k-hp | |
730 | ;; | |
731 | hp300bsd) | |
732 | basic_machine=m68k-hp | |
733 | os=-bsd | |
734 | ;; | |
735 | hp300hpux) | |
736 | basic_machine=m68k-hp | |
737 | os=-hpux | |
738 | ;; | |
739 | hp3k9[0-9][0-9] | hp9[0-9][0-9]) | |
740 | basic_machine=hppa1.0-hp | |
741 | ;; | |
742 | hp9k2[0-9][0-9] | hp9k31[0-9]) | |
743 | basic_machine=m68000-hp | |
744 | ;; | |
745 | hp9k3[2-9][0-9]) | |
746 | basic_machine=m68k-hp | |
747 | ;; | |
748 | hp9k6[0-9][0-9] | hp6[0-9][0-9]) | |
749 | basic_machine=hppa1.0-hp | |
750 | ;; | |
751 | hp9k7[0-79][0-9] | hp7[0-79][0-9]) | |
752 | basic_machine=hppa1.1-hp | |
753 | ;; | |
754 | hp9k78[0-9] | hp78[0-9]) | |
755 | # FIXME: really hppa2.0-hp | |
756 | basic_machine=hppa1.1-hp | |
757 | ;; | |
758 | hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) | |
759 | # FIXME: really hppa2.0-hp | |
760 | basic_machine=hppa1.1-hp | |
761 | ;; | |
762 | hp9k8[0-9][13679] | hp8[0-9][13679]) | |
763 | basic_machine=hppa1.1-hp | |
764 | ;; | |
765 | hp9k8[0-9][0-9] | hp8[0-9][0-9]) | |
766 | basic_machine=hppa1.0-hp | |
767 | ;; | |
768 | hppaosf) | |
769 | basic_machine=hppa1.1-hp | |
770 | os=-osf | |
771 | ;; | |
772 | hppro) | |
773 | basic_machine=hppa1.1-hp | |
774 | os=-proelf | |
775 | ;; | |
776 | i370-ibm* | ibm*) | |
777 | basic_machine=i370-ibm | |
778 | ;; | |
779 | i*86v32) | |
780 | basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` | |
781 | os=-sysv32 | |
782 | ;; | |
783 | i*86v4*) | |
784 | basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` | |
785 | os=-sysv4 | |
786 | ;; | |
787 | i*86v) | |
788 | basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` | |
789 | os=-sysv | |
790 | ;; | |
791 | i*86sol2) | |
792 | basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` | |
793 | os=-solaris2 | |
794 | ;; | |
795 | i386mach) | |
796 | basic_machine=i386-mach | |
797 | os=-mach | |
798 | ;; | |
799 | vsta) | |
800 | basic_machine=i386-unknown | |
801 | os=-vsta | |
802 | ;; | |
803 | iris | iris4d) | |
804 | basic_machine=mips-sgi | |
805 | case $os in | |
806 | -irix*) | |
807 | ;; | |
808 | *) | |
809 | os=-irix4 | |
810 | ;; | |
1028 | mips3*-*) | |
1029 | cpu=mips64 | |
1030 | ;; | |
1031 | ms1-*) | |
1032 | cpu=mt | |
1033 | ;; | |
1034 | m68knommu-*) | |
1035 | cpu=m68k | |
1036 | os=linux | |
1037 | ;; | |
1038 | m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) | |
1039 | cpu=s12z | |
1040 | ;; | |
1041 | openrisc-*) | |
1042 | cpu=or32 | |
1043 | ;; | |
1044 | parisc-*) | |
1045 | cpu=hppa | |
1046 | os=linux | |
1047 | ;; | |
1048 | pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) | |
1049 | cpu=i586 | |
1050 | ;; | |
1051 | pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) | |
1052 | cpu=i686 | |
1053 | ;; | |
1054 | pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) | |
1055 | cpu=i686 | |
1056 | ;; | |
1057 | pentium4-*) | |
1058 | cpu=i786 | |
1059 | ;; | |
1060 | pc98-*) | |
1061 | cpu=i386 | |
1062 | ;; | |
1063 | ppc-* | ppcbe-*) | |
1064 | cpu=powerpc | |
1065 | ;; | |
1066 | ppcle-* | powerpclittle-*) | |
1067 | cpu=powerpcle | |
1068 | ;; | |
1069 | ppc64-*) | |
1070 | cpu=powerpc64 | |
1071 | ;; | |
1072 | ppc64le-* | powerpc64little-*) | |
1073 | cpu=powerpc64le | |
1074 | ;; | |
1075 | sb1-*) | |
1076 | cpu=mipsisa64sb1 | |
1077 | ;; | |
1078 | sb1el-*) | |
1079 | cpu=mipsisa64sb1el | |
1080 | ;; | |
1081 | sh5e[lb]-*) | |
1082 | cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` | |
1083 | ;; | |
1084 | spur-*) | |
1085 | cpu=spur | |
1086 | ;; | |
1087 | strongarm-* | thumb-*) | |
1088 | cpu=arm | |
1089 | ;; | |
1090 | tx39-*) | |
1091 | cpu=mipstx39 | |
1092 | ;; | |
1093 | tx39el-*) | |
1094 | cpu=mipstx39el | |
1095 | ;; | |
1096 | x64-*) | |
1097 | cpu=x86_64 | |
1098 | ;; | |
1099 | xscale-* | xscalee[bl]-*) | |
1100 | cpu=`echo "$cpu" | sed 's/^xscale/arm/'` | |
1101 | ;; | |
1102 | ||
1103 | # Recognize the cannonical CPU Types that limit and/or modify the | |
1104 | # company names they are paired with. | |
1105 | cr16-*) | |
1106 | os=${os:-elf} | |
1107 | ;; | |
1108 | crisv32-* | etraxfs*-*) | |
1109 | cpu=crisv32 | |
1110 | vendor=axis | |
1111 | ;; | |
1112 | cris-* | etrax*-*) | |
1113 | cpu=cris | |
1114 | vendor=axis | |
1115 | ;; | |
1116 | crx-*) | |
1117 | os=${os:-elf} | |
1118 | ;; | |
1119 | neo-tandem) | |
1120 | cpu=neo | |
1121 | vendor=tandem | |
1122 | ;; | |
1123 | nse-tandem) | |
1124 | cpu=nse | |
1125 | vendor=tandem | |
1126 | ;; | |
1127 | nsr-tandem) | |
1128 | cpu=nsr | |
1129 | vendor=tandem | |
1130 | ;; | |
1131 | nsv-tandem) | |
1132 | cpu=nsv | |
1133 | vendor=tandem | |
1134 | ;; | |
1135 | nsx-tandem) | |
1136 | cpu=nsx | |
1137 | vendor=tandem | |
1138 | ;; | |
1139 | s390-*) | |
1140 | cpu=s390 | |
1141 | vendor=ibm | |
1142 | ;; | |
1143 | s390x-*) | |
1144 | cpu=s390x | |
1145 | vendor=ibm | |
1146 | ;; | |
1147 | tile*-*) | |
1148 | os=${os:-linux-gnu} | |
1149 | ;; | |
1150 | ||
1151 | *) | |
1152 | # Recognize the cannonical CPU types that are allowed with any | |
1153 | # company name. | |
1154 | case $cpu in | |
1155 | 1750a | 580 \ | |
1156 | | a29k \ | |
1157 | | aarch64 | aarch64_be \ | |
1158 | | abacus \ | |
1159 | | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ | |
1160 | | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ | |
1161 | | alphapca5[67] | alpha64pca5[67] \ | |
1162 | | am33_2.0 \ | |
1163 | | arc | arceb \ | |
1164 | | arm | arm[lb]e | arme[lb] | armv* \ | |
1165 | | avr | avr32 \ | |
1166 | | asmjs \ | |
1167 | | ba \ | |
1168 | | be32 | be64 \ | |
1169 | | bfin | bs2000 \ | |
1170 | | c[123]* | c30 | [cjt]90 | c4x \ | |
1171 | | c8051 | clipper | craynv | csky | cydra \ | |
1172 | | d10v | d30v | dlx | dsp16xx \ | |
1173 | | e2k | elxsi | epiphany \ | |
1174 | | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ | |
1175 | | h8300 | h8500 \ | |
1176 | | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | |
1177 | | hexagon \ | |
1178 | | i370 | i*86 | i860 | i960 | ia16 | ia64 \ | |
1179 | | ip2k | iq2000 \ | |
1180 | | k1om \ | |
1181 | | le32 | le64 \ | |
1182 | | lm32 \ | |
1183 | | m32c | m32r | m32rle \ | |
1184 | | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k | v70 | w65 \ | |
1185 | | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip \ | |
1186 | | m88110 | m88k | maxq | mb | mcore | mep | metag \ | |
1187 | | microblaze | microblazeel \ | |
1188 | | mips | mipsbe | mipseb | mipsel | mipsle \ | |
1189 | | mips16 \ | |
1190 | | mips64 | mips64el \ | |
1191 | | mips64octeon | mips64octeonel \ | |
1192 | | mips64orion | mips64orionel \ | |
1193 | | mips64r5900 | mips64r5900el \ | |
1194 | | mips64vr | mips64vrel \ | |
1195 | | mips64vr4100 | mips64vr4100el \ | |
1196 | | mips64vr4300 | mips64vr4300el \ | |
1197 | | mips64vr5000 | mips64vr5000el \ | |
1198 | | mips64vr5900 | mips64vr5900el \ | |
1199 | | mipsisa32 | mipsisa32el \ | |
1200 | | mipsisa32r2 | mipsisa32r2el \ | |
1201 | | mipsisa32r6 | mipsisa32r6el \ | |
1202 | | mipsisa64 | mipsisa64el \ | |
1203 | | mipsisa64r2 | mipsisa64r2el \ | |
1204 | | mipsisa64r6 | mipsisa64r6el \ | |
1205 | | mipsisa64sb1 | mipsisa64sb1el \ | |
1206 | | mipsisa64sr71k | mipsisa64sr71kel \ | |
1207 | | mipsr5900 | mipsr5900el \ | |
1208 | | mipstx39 | mipstx39el \ | |
1209 | | mmix \ | |
1210 | | mn10200 | mn10300 \ | |
1211 | | moxie \ | |
1212 | | mt \ | |
1213 | | msp430 \ | |
1214 | | nds32 | nds32le | nds32be \ | |
1215 | | nfp \ | |
1216 | | nios | nios2 | nios2eb | nios2el \ | |
1217 | | none | np1 | ns16k | ns32k \ | |
1218 | | open8 \ | |
1219 | | or1k* \ | |
1220 | | or32 \ | |
1221 | | orion \ | |
1222 | | pdp10 | pdp11 | pj | pjl | pn | power \ | |
1223 | | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ | |
1224 | | pru \ | |
1225 | | pyramid \ | |
1226 | | riscv | riscv32 | riscv64 \ | |
1227 | | rl78 | romp | rs6000 | rx \ | |
1228 | | score \ | |
1229 | | sh | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ | |
1230 | | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ | |
1231 | | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ | |
1232 | | sparclite \ | |
1233 | | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ | |
1234 | | spu \ | |
1235 | | tahoe \ | |
1236 | | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ | |
1237 | | tron \ | |
1238 | | ubicom32 \ | |
1239 | | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ | |
1240 | | vax \ | |
1241 | | visium \ | |
1242 | | wasm32 \ | |
1243 | | we32k \ | |
1244 | | x86 | x86_64 | xc16x | xgate | xps100 \ | |
1245 | | xstormy16 | xtensa* \ | |
1246 | | ymp \ | |
1247 | | z8k | z80) | |
1248 | ;; | |
1249 | ||
1250 | *) | |
1251 | echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 | |
1252 | exit 1 | |
1253 | ;; | |
811 | 1254 | esac |
812 | 1255 | ;; |
813 | isi68 | isi) | |
814 | basic_machine=m68k-isi | |
815 | os=-sysv | |
816 | ;; | |
817 | leon-*|leon[3-9]-*) | |
818 | basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` | |
819 | ;; | |
820 | m68knommu) | |
821 | basic_machine=m68k-unknown | |
822 | os=-linux | |
823 | ;; | |
824 | m68knommu-*) | |
825 | basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
826 | os=-linux | |
827 | ;; | |
828 | magnum | m3230) | |
829 | basic_machine=mips-mips | |
830 | os=-sysv | |
831 | ;; | |
832 | merlin) | |
833 | basic_machine=ns32k-utek | |
834 | os=-sysv | |
835 | ;; | |
836 | microblaze*) | |
837 | basic_machine=microblaze-xilinx | |
838 | ;; | |
839 | mingw64) | |
840 | basic_machine=x86_64-pc | |
841 | os=-mingw64 | |
842 | ;; | |
843 | mingw32) | |
844 | basic_machine=i686-pc | |
845 | os=-mingw32 | |
846 | ;; | |
847 | mingw32ce) | |
848 | basic_machine=arm-unknown | |
849 | os=-mingw32ce | |
850 | ;; | |
851 | miniframe) | |
852 | basic_machine=m68000-convergent | |
853 | ;; | |
854 | *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) | |
855 | basic_machine=m68k-atari | |
856 | os=-mint | |
857 | ;; | |
858 | mips3*-*) | |
859 | basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` | |
860 | ;; | |
861 | mips3*) | |
862 | basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown | |
863 | ;; | |
864 | monitor) | |
865 | basic_machine=m68k-rom68k | |
866 | os=-coff | |
867 | ;; | |
868 | morphos) | |
869 | basic_machine=powerpc-unknown | |
870 | os=-morphos | |
871 | ;; | |
872 | moxiebox) | |
873 | basic_machine=moxie-unknown | |
874 | os=-moxiebox | |
875 | ;; | |
876 | msdos) | |
877 | basic_machine=i386-pc | |
878 | os=-msdos | |
879 | ;; | |
880 | ms1-*) | |
881 | basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` | |
882 | ;; | |
883 | msys) | |
884 | basic_machine=i686-pc | |
885 | os=-msys | |
886 | ;; | |
887 | mvs) | |
888 | basic_machine=i370-ibm | |
889 | os=-mvs | |
890 | ;; | |
891 | nacl) | |
892 | basic_machine=le32-unknown | |
893 | os=-nacl | |
894 | ;; | |
895 | ncr3000) | |
896 | basic_machine=i486-ncr | |
897 | os=-sysv4 | |
898 | ;; | |
899 | netbsd386) | |
900 | basic_machine=i386-unknown | |
901 | os=-netbsd | |
902 | ;; | |
903 | netwinder) | |
904 | basic_machine=armv4l-rebel | |
905 | os=-linux | |
906 | ;; | |
907 | news | news700 | news800 | news900) | |
908 | basic_machine=m68k-sony | |
909 | os=-newsos | |
910 | ;; | |
911 | news1000) | |
912 | basic_machine=m68030-sony | |
913 | os=-newsos | |
914 | ;; | |
915 | news-3600 | risc-news) | |
916 | basic_machine=mips-sony | |
917 | os=-newsos | |
918 | ;; | |
919 | necv70) | |
920 | basic_machine=v70-nec | |
921 | os=-sysv | |
922 | ;; | |
923 | next | m*-next) | |
924 | basic_machine=m68k-next | |
925 | case $os in | |
926 | -nextstep* ) | |
927 | ;; | |
928 | -ns2*) | |
929 | os=-nextstep2 | |
930 | ;; | |
931 | *) | |
932 | os=-nextstep3 | |
933 | ;; | |
934 | esac | |
935 | ;; | |
936 | nh3000) | |
937 | basic_machine=m68k-harris | |
938 | os=-cxux | |
939 | ;; | |
940 | nh[45]000) | |
941 | basic_machine=m88k-harris | |
942 | os=-cxux | |
943 | ;; | |
944 | nindy960) | |
945 | basic_machine=i960-intel | |
946 | os=-nindy | |
947 | ;; | |
948 | mon960) | |
949 | basic_machine=i960-intel | |
950 | os=-mon960 | |
951 | ;; | |
952 | nonstopux) | |
953 | basic_machine=mips-compaq | |
954 | os=-nonstopux | |
955 | ;; | |
956 | np1) | |
957 | basic_machine=np1-gould | |
958 | ;; | |
959 | neo-tandem) | |
960 | basic_machine=neo-tandem | |
961 | ;; | |
962 | nse-tandem) | |
963 | basic_machine=nse-tandem | |
964 | ;; | |
965 | nsr-tandem) | |
966 | basic_machine=nsr-tandem | |
967 | ;; | |
968 | nsv-tandem) | |
969 | basic_machine=nsv-tandem | |
970 | ;; | |
971 | nsx-tandem) | |
972 | basic_machine=nsx-tandem | |
973 | ;; | |
974 | op50n-* | op60c-*) | |
975 | basic_machine=hppa1.1-oki | |
976 | os=-proelf | |
977 | ;; | |
978 | openrisc | openrisc-*) | |
979 | basic_machine=or32-unknown | |
980 | ;; | |
981 | os400) | |
982 | basic_machine=powerpc-ibm | |
983 | os=-os400 | |
984 | ;; | |
985 | OSE68000 | ose68000) | |
986 | basic_machine=m68000-ericsson | |
987 | os=-ose | |
988 | ;; | |
989 | os68k) | |
990 | basic_machine=m68k-none | |
991 | os=-os68k | |
992 | ;; | |
993 | pa-hitachi) | |
994 | basic_machine=hppa1.1-hitachi | |
995 | os=-hiuxwe2 | |
996 | ;; | |
997 | paragon) | |
998 | basic_machine=i860-intel | |
999 | os=-osf | |
1000 | ;; | |
1001 | parisc) | |
1002 | basic_machine=hppa-unknown | |
1003 | os=-linux | |
1004 | ;; | |
1005 | parisc-*) | |
1006 | basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1007 | os=-linux | |
1008 | ;; | |
1009 | pbd) | |
1010 | basic_machine=sparc-tti | |
1011 | ;; | |
1012 | pbb) | |
1013 | basic_machine=m68k-tti | |
1014 | ;; | |
1015 | pc532 | pc532-*) | |
1016 | basic_machine=ns32k-pc532 | |
1017 | ;; | |
1018 | pc98) | |
1019 | basic_machine=i386-pc | |
1020 | ;; | |
1021 | pc98-*) | |
1022 | basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1023 | ;; | |
1024 | pentium | p5 | k5 | k6 | nexgen | viac3) | |
1025 | basic_machine=i586-pc | |
1026 | ;; | |
1027 | pentiumpro | p6 | 6x86 | athlon | athlon_*) | |
1028 | basic_machine=i686-pc | |
1029 | ;; | |
1030 | pentiumii | pentium2 | pentiumiii | pentium3) | |
1031 | basic_machine=i686-pc | |
1032 | ;; | |
1033 | pentium4) | |
1034 | basic_machine=i786-pc | |
1035 | ;; | |
1036 | pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) | |
1037 | basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1038 | ;; | |
1039 | pentiumpro-* | p6-* | 6x86-* | athlon-*) | |
1040 | basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1041 | ;; | |
1042 | pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) | |
1043 | basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1044 | ;; | |
1045 | pentium4-*) | |
1046 | basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1047 | ;; | |
1048 | pn) | |
1049 | basic_machine=pn-gould | |
1050 | ;; | |
1051 | power) basic_machine=power-ibm | |
1052 | ;; | |
1053 | ppc | ppcbe) basic_machine=powerpc-unknown | |
1054 | ;; | |
1055 | ppc-* | ppcbe-*) | |
1056 | basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1057 | ;; | |
1058 | ppcle | powerpclittle) | |
1059 | basic_machine=powerpcle-unknown | |
1060 | ;; | |
1061 | ppcle-* | powerpclittle-*) | |
1062 | basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1063 | ;; | |
1064 | ppc64) basic_machine=powerpc64-unknown | |
1065 | ;; | |
1066 | ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1067 | ;; | |
1068 | ppc64le | powerpc64little) | |
1069 | basic_machine=powerpc64le-unknown | |
1070 | ;; | |
1071 | ppc64le-* | powerpc64little-*) | |
1072 | basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1073 | ;; | |
1074 | ps2) | |
1075 | basic_machine=i386-ibm | |
1076 | ;; | |
1077 | pw32) | |
1078 | basic_machine=i586-unknown | |
1079 | os=-pw32 | |
1080 | ;; | |
1081 | rdos | rdos64) | |
1082 | basic_machine=x86_64-pc | |
1083 | os=-rdos | |
1084 | ;; | |
1085 | rdos32) | |
1086 | basic_machine=i386-pc | |
1087 | os=-rdos | |
1088 | ;; | |
1089 | rom68k) | |
1090 | basic_machine=m68k-rom68k | |
1091 | os=-coff | |
1092 | ;; | |
1093 | rm[46]00) | |
1094 | basic_machine=mips-siemens | |
1095 | ;; | |
1096 | rtpc | rtpc-*) | |
1097 | basic_machine=romp-ibm | |
1098 | ;; | |
1099 | s390 | s390-*) | |
1100 | basic_machine=s390-ibm | |
1101 | ;; | |
1102 | s390x | s390x-*) | |
1103 | basic_machine=s390x-ibm | |
1104 | ;; | |
1105 | sa29200) | |
1106 | basic_machine=a29k-amd | |
1107 | os=-udi | |
1108 | ;; | |
1109 | sb1) | |
1110 | basic_machine=mipsisa64sb1-unknown | |
1111 | ;; | |
1112 | sb1el) | |
1113 | basic_machine=mipsisa64sb1el-unknown | |
1114 | ;; | |
1115 | sde) | |
1116 | basic_machine=mipsisa32-sde | |
1117 | os=-elf | |
1118 | ;; | |
1119 | sei) | |
1120 | basic_machine=mips-sei | |
1121 | os=-seiux | |
1122 | ;; | |
1123 | sequent) | |
1124 | basic_machine=i386-sequent | |
1125 | ;; | |
1126 | sh5el) | |
1127 | basic_machine=sh5le-unknown | |
1128 | ;; | |
1129 | simso-wrs) | |
1130 | basic_machine=sparclite-wrs | |
1131 | os=-vxworks | |
1132 | ;; | |
1133 | sps7) | |
1134 | basic_machine=m68k-bull | |
1135 | os=-sysv2 | |
1136 | ;; | |
1137 | spur) | |
1138 | basic_machine=spur-unknown | |
1139 | ;; | |
1140 | st2000) | |
1141 | basic_machine=m68k-tandem | |
1142 | ;; | |
1143 | stratus) | |
1144 | basic_machine=i860-stratus | |
1145 | os=-sysv4 | |
1146 | ;; | |
1147 | strongarm-* | thumb-*) | |
1148 | basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` | |
1149 | ;; | |
1150 | sun2) | |
1151 | basic_machine=m68000-sun | |
1152 | ;; | |
1153 | sun2os3) | |
1154 | basic_machine=m68000-sun | |
1155 | os=-sunos3 | |
1156 | ;; | |
1157 | sun2os4) | |
1158 | basic_machine=m68000-sun | |
1159 | os=-sunos4 | |
1160 | ;; | |
1161 | sun3os3) | |
1162 | basic_machine=m68k-sun | |
1163 | os=-sunos3 | |
1164 | ;; | |
1165 | sun3os4) | |
1166 | basic_machine=m68k-sun | |
1167 | os=-sunos4 | |
1168 | ;; | |
1169 | sun4os3) | |
1170 | basic_machine=sparc-sun | |
1171 | os=-sunos3 | |
1172 | ;; | |
1173 | sun4os4) | |
1174 | basic_machine=sparc-sun | |
1175 | os=-sunos4 | |
1176 | ;; | |
1177 | sun4sol2) | |
1178 | basic_machine=sparc-sun | |
1179 | os=-solaris2 | |
1180 | ;; | |
1181 | sun3 | sun3-*) | |
1182 | basic_machine=m68k-sun | |
1183 | ;; | |
1184 | sun4) | |
1185 | basic_machine=sparc-sun | |
1186 | ;; | |
1187 | sun386 | sun386i | roadrunner) | |
1188 | basic_machine=i386-sun | |
1189 | ;; | |
1190 | sv1) | |
1191 | basic_machine=sv1-cray | |
1192 | os=-unicos | |
1193 | ;; | |
1194 | symmetry) | |
1195 | basic_machine=i386-sequent | |
1196 | os=-dynix | |
1197 | ;; | |
1198 | t3e) | |
1199 | basic_machine=alphaev5-cray | |
1200 | os=-unicos | |
1201 | ;; | |
1202 | t90) | |
1203 | basic_machine=t90-cray | |
1204 | os=-unicos | |
1205 | ;; | |
1206 | tile*) | |
1207 | basic_machine=$basic_machine-unknown | |
1208 | os=-linux-gnu | |
1209 | ;; | |
1210 | tx39) | |
1211 | basic_machine=mipstx39-unknown | |
1212 | ;; | |
1213 | tx39el) | |
1214 | basic_machine=mipstx39el-unknown | |
1215 | ;; | |
1216 | toad1) | |
1217 | basic_machine=pdp10-xkl | |
1218 | os=-tops20 | |
1219 | ;; | |
1220 | tower | tower-32) | |
1221 | basic_machine=m68k-ncr | |
1222 | ;; | |
1223 | tpf) | |
1224 | basic_machine=s390x-ibm | |
1225 | os=-tpf | |
1226 | ;; | |
1227 | udi29k) | |
1228 | basic_machine=a29k-amd | |
1229 | os=-udi | |
1230 | ;; | |
1231 | ultra3) | |
1232 | basic_machine=a29k-nyu | |
1233 | os=-sym1 | |
1234 | ;; | |
1235 | v810 | necv810) | |
1236 | basic_machine=v810-nec | |
1237 | os=-none | |
1238 | ;; | |
1239 | vaxv) | |
1240 | basic_machine=vax-dec | |
1241 | os=-sysv | |
1242 | ;; | |
1243 | vms) | |
1244 | basic_machine=vax-dec | |
1245 | os=-vms | |
1246 | ;; | |
1247 | vpp*|vx|vx-*) | |
1248 | basic_machine=f301-fujitsu | |
1249 | ;; | |
1250 | vxworks960) | |
1251 | basic_machine=i960-wrs | |
1252 | os=-vxworks | |
1253 | ;; | |
1254 | vxworks68) | |
1255 | basic_machine=m68k-wrs | |
1256 | os=-vxworks | |
1257 | ;; | |
1258 | vxworks29k) | |
1259 | basic_machine=a29k-wrs | |
1260 | os=-vxworks | |
1261 | ;; | |
1262 | w65*) | |
1263 | basic_machine=w65-wdc | |
1264 | os=-none | |
1265 | ;; | |
1266 | w89k-*) | |
1267 | basic_machine=hppa1.1-winbond | |
1268 | os=-proelf | |
1269 | ;; | |
1270 | x64) | |
1271 | basic_machine=x86_64-pc | |
1272 | ;; | |
1273 | xbox) | |
1274 | basic_machine=i686-pc | |
1275 | os=-mingw32 | |
1276 | ;; | |
1277 | xps | xps100) | |
1278 | basic_machine=xps100-honeywell | |
1279 | ;; | |
1280 | xscale-* | xscalee[bl]-*) | |
1281 | basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` | |
1282 | ;; | |
1283 | ymp) | |
1284 | basic_machine=ymp-cray | |
1285 | os=-unicos | |
1286 | ;; | |
1287 | none) | |
1288 | basic_machine=none-none | |
1289 | os=-none | |
1290 | ;; | |
1291 | ||
1292 | # Here we handle the default manufacturer of certain CPU types. It is in | |
1293 | # some cases the only manufacturer, in others, it is the most popular. | |
1294 | w89k) | |
1295 | basic_machine=hppa1.1-winbond | |
1296 | ;; | |
1297 | op50n) | |
1298 | basic_machine=hppa1.1-oki | |
1299 | ;; | |
1300 | op60c) | |
1301 | basic_machine=hppa1.1-oki | |
1302 | ;; | |
1303 | romp) | |
1304 | basic_machine=romp-ibm | |
1305 | ;; | |
1306 | mmix) | |
1307 | basic_machine=mmix-knuth | |
1308 | ;; | |
1309 | rs6000) | |
1310 | basic_machine=rs6000-ibm | |
1311 | ;; | |
1312 | vax) | |
1313 | basic_machine=vax-dec | |
1314 | ;; | |
1315 | pdp11) | |
1316 | basic_machine=pdp11-dec | |
1317 | ;; | |
1318 | we32k) | |
1319 | basic_machine=we32k-att | |
1320 | ;; | |
1321 | sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) | |
1322 | basic_machine=sh-unknown | |
1323 | ;; | |
1324 | cydra) | |
1325 | basic_machine=cydra-cydrome | |
1326 | ;; | |
1327 | orion) | |
1328 | basic_machine=orion-highlevel | |
1329 | ;; | |
1330 | orion105) | |
1331 | basic_machine=clipper-highlevel | |
1332 | ;; | |
1333 | mac | mpw | mac-mpw) | |
1334 | basic_machine=m68k-apple | |
1335 | ;; | |
1336 | pmac | pmac-mpw) | |
1337 | basic_machine=powerpc-apple | |
1338 | ;; | |
1339 | *-unknown) | |
1340 | # Make sure to match an already-canonicalized machine name. | |
1341 | ;; | |
1342 | *) | |
1343 | echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 | |
1344 | exit 1 | |
1345 | ;; | |
1346 | 1256 | esac |
1347 | 1257 | |
1348 | 1258 | # Here we canonicalize certain aliases for manufacturers. |
1349 | case $basic_machine in | |
1350 | *-digital*) | |
1351 | basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` | |
1352 | ;; | |
1353 | *-commodore*) | |
1354 | basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` | |
1259 | case $vendor in | |
1260 | digital*) | |
1261 | vendor=dec | |
1262 | ;; | |
1263 | commodore*) | |
1264 | vendor=cbm | |
1355 | 1265 | ;; |
1356 | 1266 | *) |
1357 | 1267 | ;; |
1364 | 1274 | case $os in |
1365 | 1275 | # First match some system type aliases that might get confused |
1366 | 1276 | # with valid system types. |
1367 | # -solaris* is a basic system type, with this one exception. | |
1368 | -auroraux) | |
1369 | os=-auroraux | |
1370 | ;; | |
1371 | -solaris1 | -solaris1.*) | |
1277 | # solaris* is a basic system type, with this one exception. | |
1278 | auroraux) | |
1279 | os=auroraux | |
1280 | ;; | |
1281 | bluegene*) | |
1282 | os=cnk | |
1283 | ;; | |
1284 | solaris1 | solaris1.*) | |
1372 | 1285 | os=`echo $os | sed -e 's|solaris1|sunos4|'` |
1373 | 1286 | ;; |
1374 | -solaris) | |
1375 | os=-solaris2 | |
1376 | ;; | |
1377 | -unixware*) | |
1378 | os=-sysv4.2uw | |
1379 | ;; | |
1380 | -gnu/linux*) | |
1287 | solaris) | |
1288 | os=solaris2 | |
1289 | ;; | |
1290 | unixware*) | |
1291 | os=sysv4.2uw | |
1292 | ;; | |
1293 | gnu/linux*) | |
1381 | 1294 | os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` |
1382 | 1295 | ;; |
1383 | 1296 | # es1800 is here to avoid being matched by es* (a different OS) |
1384 | -es1800*) | |
1385 | os=-ose | |
1297 | es1800*) | |
1298 | os=ose | |
1299 | ;; | |
1300 | # Some version numbers need modification | |
1301 | chorusos*) | |
1302 | os=chorusos | |
1303 | ;; | |
1304 | isc) | |
1305 | os=isc2.2 | |
1306 | ;; | |
1307 | sco6) | |
1308 | os=sco5v6 | |
1309 | ;; | |
1310 | sco5) | |
1311 | os=sco3.2v5 | |
1312 | ;; | |
1313 | sco4) | |
1314 | os=sco3.2v4 | |
1315 | ;; | |
1316 | sco3.2.[4-9]*) | |
1317 | os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` | |
1318 | ;; | |
1319 | sco3.2v[4-9]* | sco5v6*) | |
1320 | # Don't forget version if it is 3.2v4 or newer. | |
1321 | ;; | |
1322 | scout) | |
1323 | # Don't match below | |
1324 | ;; | |
1325 | sco*) | |
1326 | os=sco3.2v2 | |
1327 | ;; | |
1328 | psos*) | |
1329 | os=psos | |
1386 | 1330 | ;; |
1387 | 1331 | # Now accept the basic system types. |
1388 | 1332 | # The portable systems comes first. |
1389 | 1333 | # Each alternative MUST end in a * to match a version number. |
1390 | # -sysv* is not here because it comes later, after sysvr4. | |
1391 | -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | |
1392 | | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | |
1393 | | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | |
1394 | | -sym* | -kopensolaris* | -plan9* \ | |
1395 | | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | |
1396 | | -aos* | -aros* | -cloudabi* | -sortix* \ | |
1397 | | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | |
1398 | | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | |
1399 | | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ | |
1400 | | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | |
1401 | | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | |
1402 | | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | |
1403 | | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | |
1404 | | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \ | |
1405 | | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | |
1406 | | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | |
1407 | | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | |
1408 | | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | |
1409 | | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | |
1410 | | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | |
1411 | | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | |
1412 | | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | |
1413 | | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | |
1414 | | -morphos* | -superux* | -rtmk* | -windiss* \ | |
1415 | | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | |
1416 | | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | |
1417 | | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ | |
1418 | | -midnightbsd*) | |
1334 | # sysv* is not here because it comes later, after sysvr4. | |
1335 | gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ | |
1336 | | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\ | |
1337 | | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ | |
1338 | | sym* | kopensolaris* | plan9* \ | |
1339 | | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | |
1340 | | aos* | aros* | cloudabi* | sortix* \ | |
1341 | | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ | |
1342 | | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ | |
1343 | | knetbsd* | mirbsd* | netbsd* \ | |
1344 | | bitrig* | openbsd* | solidbsd* | libertybsd* \ | |
1345 | | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ | |
1346 | | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ | |
1347 | | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ | |
1348 | | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \ | |
1349 | | chorusrdb* | cegcc* | glidix* \ | |
1350 | | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ | |
1351 | | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \ | |
1352 | | linux-newlib* | linux-musl* | linux-uclibc* \ | |
1353 | | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | |
1354 | | interix* | uwin* | mks* | rhapsody* | darwin* \ | |
1355 | | openstep* | oskit* | conix* | pw32* | nonstopux* \ | |
1356 | | storm-chaos* | tops10* | tenex* | tops20* | its* \ | |
1357 | | os2* | vos* | palmos* | uclinux* | nucleus* \ | |
1358 | | morphos* | superux* | rtmk* | windiss* \ | |
1359 | | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ | |
1360 | | skyos* | haiku* | rdos* | toppers* | drops* | es* \ | |
1361 | | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | |
1362 | | midnightbsd*) | |
1419 | 1363 | # Remember, each alternative MUST END IN *, to match a version number. |
1420 | 1364 | ;; |
1421 | -qnx*) | |
1422 | case $basic_machine in | |
1423 | x86-* | i*86-*) | |
1365 | qnx*) | |
1366 | case $cpu in | |
1367 | x86 | i*86) | |
1424 | 1368 | ;; |
1425 | 1369 | *) |
1426 | os=-nto$os | |
1370 | os=nto-$os | |
1427 | 1371 | ;; |
1428 | 1372 | esac |
1429 | 1373 | ;; |
1430 | -nto-qnx*) | |
1431 | ;; | |
1432 | -nto*) | |
1374 | hiux*) | |
1375 | os=hiuxwe2 | |
1376 | ;; | |
1377 | nto-qnx*) | |
1378 | ;; | |
1379 | nto*) | |
1433 | 1380 | os=`echo $os | sed -e 's|nto|nto-qnx|'` |
1434 | 1381 | ;; |
1435 | -sim | -xray | -os68k* | -v88r* \ | |
1436 | | -windows* | -osx | -abug | -netware* | -os9* \ | |
1437 | | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) | |
1438 | ;; | |
1439 | -mac*) | |
1382 | sim | xray | os68k* | v88r* \ | |
1383 | | windows* | osx | abug | netware* | os9* \ | |
1384 | | macos* | mpw* | magic* | mmixware* | mon960* | lnews*) | |
1385 | ;; | |
1386 | linux-dietlibc) | |
1387 | os=linux-dietlibc | |
1388 | ;; | |
1389 | linux*) | |
1390 | os=`echo $os | sed -e 's|linux|linux-gnu|'` | |
1391 | ;; | |
1392 | lynx*178) | |
1393 | os=lynxos178 | |
1394 | ;; | |
1395 | lynx*5) | |
1396 | os=lynxos5 | |
1397 | ;; | |
1398 | lynx*) | |
1399 | os=lynxos | |
1400 | ;; | |
1401 | mac*) | |
1440 | 1402 | os=`echo "$os" | sed -e 's|mac|macos|'` |
1441 | 1403 | ;; |
1442 | -linux-dietlibc) | |
1443 | os=-linux-dietlibc | |
1444 | ;; | |
1445 | -linux*) | |
1446 | os=`echo $os | sed -e 's|linux|linux-gnu|'` | |
1447 | ;; | |
1448 | -sunos5*) | |
1404 | opened*) | |
1405 | os=openedition | |
1406 | ;; | |
1407 | os400*) | |
1408 | os=os400 | |
1409 | ;; | |
1410 | sunos5*) | |
1449 | 1411 | os=`echo "$os" | sed -e 's|sunos5|solaris2|'` |
1450 | 1412 | ;; |
1451 | -sunos6*) | |
1413 | sunos6*) | |
1452 | 1414 | os=`echo "$os" | sed -e 's|sunos6|solaris3|'` |
1453 | 1415 | ;; |
1454 | -opened*) | |
1455 | os=-openedition | |
1456 | ;; | |
1457 | -os400*) | |
1458 | os=-os400 | |
1459 | ;; | |
1460 | -wince*) | |
1461 | os=-wince | |
1462 | ;; | |
1463 | -utek*) | |
1464 | os=-bsd | |
1465 | ;; | |
1466 | -dynix*) | |
1467 | os=-bsd | |
1468 | ;; | |
1469 | -acis*) | |
1470 | os=-aos | |
1471 | ;; | |
1472 | -atheos*) | |
1473 | os=-atheos | |
1474 | ;; | |
1475 | -syllable*) | |
1476 | os=-syllable | |
1477 | ;; | |
1478 | -386bsd) | |
1479 | os=-bsd | |
1480 | ;; | |
1481 | -ctix* | -uts*) | |
1482 | os=-sysv | |
1483 | ;; | |
1484 | -nova*) | |
1485 | os=-rtmk-nova | |
1486 | ;; | |
1487 | -ns2) | |
1488 | os=-nextstep2 | |
1489 | ;; | |
1490 | -nsk*) | |
1491 | os=-nsk | |
1416 | wince*) | |
1417 | os=wince | |
1418 | ;; | |
1419 | utek*) | |
1420 | os=bsd | |
1421 | ;; | |
1422 | dynix*) | |
1423 | os=bsd | |
1424 | ;; | |
1425 | acis*) | |
1426 | os=aos | |
1427 | ;; | |
1428 | atheos*) | |
1429 | os=atheos | |
1430 | ;; | |
1431 | syllable*) | |
1432 | os=syllable | |
1433 | ;; | |
1434 | 386bsd) | |
1435 | os=bsd | |
1436 | ;; | |
1437 | ctix* | uts*) | |
1438 | os=sysv | |
1439 | ;; | |
1440 | nova*) | |
1441 | os=rtmk-nova | |
1442 | ;; | |
1443 | ns2) | |
1444 | os=nextstep2 | |
1445 | ;; | |
1446 | nsk*) | |
1447 | os=nsk | |
1492 | 1448 | ;; |
1493 | 1449 | # Preserve the version number of sinix5. |
1494 | -sinix5.*) | |
1450 | sinix5.*) | |
1495 | 1451 | os=`echo $os | sed -e 's|sinix|sysv|'` |
1496 | 1452 | ;; |
1497 | -sinix*) | |
1498 | os=-sysv4 | |
1499 | ;; | |
1500 | -tpf*) | |
1501 | os=-tpf | |
1502 | ;; | |
1503 | -triton*) | |
1504 | os=-sysv3 | |
1505 | ;; | |
1506 | -oss*) | |
1507 | os=-sysv3 | |
1508 | ;; | |
1509 | -svr4*) | |
1510 | os=-sysv4 | |
1511 | ;; | |
1512 | -svr3) | |
1513 | os=-sysv3 | |
1514 | ;; | |
1515 | -sysvr4) | |
1516 | os=-sysv4 | |
1517 | ;; | |
1518 | # This must come after -sysvr4. | |
1519 | -sysv*) | |
1520 | ;; | |
1521 | -ose*) | |
1522 | os=-ose | |
1523 | ;; | |
1524 | -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) | |
1525 | os=-mint | |
1526 | ;; | |
1527 | -zvmoe) | |
1528 | os=-zvmoe | |
1529 | ;; | |
1530 | -dicos*) | |
1531 | os=-dicos | |
1532 | ;; | |
1533 | -pikeos*) | |
1453 | sinix*) | |
1454 | os=sysv4 | |
1455 | ;; | |
1456 | tpf*) | |
1457 | os=tpf | |
1458 | ;; | |
1459 | triton*) | |
1460 | os=sysv3 | |
1461 | ;; | |
1462 | oss*) | |
1463 | os=sysv3 | |
1464 | ;; | |
1465 | svr4*) | |
1466 | os=sysv4 | |
1467 | ;; | |
1468 | svr3) | |
1469 | os=sysv3 | |
1470 | ;; | |
1471 | sysvr4) | |
1472 | os=sysv4 | |
1473 | ;; | |
1474 | # This must come after sysvr4. | |
1475 | sysv*) | |
1476 | ;; | |
1477 | ose*) | |
1478 | os=ose | |
1479 | ;; | |
1480 | *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) | |
1481 | os=mint | |
1482 | ;; | |
1483 | zvmoe) | |
1484 | os=zvmoe | |
1485 | ;; | |
1486 | dicos*) | |
1487 | os=dicos | |
1488 | ;; | |
1489 | pikeos*) | |
1534 | 1490 | # Until real need of OS specific support for |
1535 | 1491 | # particular features comes up, bare metal |
1536 | 1492 | # configurations are quite functional. |
1537 | case $basic_machine in | |
1493 | case $cpu in | |
1538 | 1494 | arm*) |
1539 | os=-eabi | |
1495 | os=eabi | |
1540 | 1496 | ;; |
1541 | 1497 | *) |
1542 | os=-elf | |
1498 | os=elf | |
1543 | 1499 | ;; |
1544 | 1500 | esac |
1545 | 1501 | ;; |
1546 | -nacl*) | |
1547 | ;; | |
1548 | -ios) | |
1549 | ;; | |
1550 | -none) | |
1551 | ;; | |
1552 | -*-eabi) | |
1553 | case $basic_machine in | |
1554 | arm*) | |
1555 | ;; | |
1556 | esac | |
1502 | nacl*) | |
1503 | ;; | |
1504 | ios) | |
1505 | ;; | |
1506 | none) | |
1507 | ;; | |
1508 | *-eabi) | |
1557 | 1509 | ;; |
1558 | 1510 | *) |
1559 | # Get rid of the `-' at the beginning of $os. | |
1560 | os=`echo $os | sed 's/[^-]*-//'` | |
1561 | 1511 | echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 |
1562 | 1512 | exit 1 |
1563 | 1513 | ;; |
1574 | 1524 | # will signal an error saying that MANUFACTURER isn't an operating |
1575 | 1525 | # system, and we'll never get to this point. |
1576 | 1526 | |
1577 | case $basic_machine in | |
1527 | case $cpu-$vendor in | |
1578 | 1528 | score-*) |
1579 | os=-elf | |
1529 | os=elf | |
1580 | 1530 | ;; |
1581 | 1531 | spu-*) |
1582 | os=-elf | |
1532 | os=elf | |
1583 | 1533 | ;; |
1584 | 1534 | *-acorn) |
1585 | os=-riscix1.2 | |
1535 | os=riscix1.2 | |
1586 | 1536 | ;; |
1587 | 1537 | arm*-rebel) |
1588 | os=-linux | |
1538 | os=linux | |
1589 | 1539 | ;; |
1590 | 1540 | arm*-semi) |
1591 | os=-aout | |
1541 | os=aout | |
1592 | 1542 | ;; |
1593 | 1543 | c4x-* | tic4x-*) |
1594 | os=-coff | |
1544 | os=coff | |
1595 | 1545 | ;; |
1596 | 1546 | c8051-*) |
1597 | os=-elf | |
1547 | os=elf | |
1548 | ;; | |
1549 | clipper-intergraph) | |
1550 | os=clix | |
1598 | 1551 | ;; |
1599 | 1552 | hexagon-*) |
1600 | os=-elf | |
1553 | os=elf | |
1601 | 1554 | ;; |
1602 | 1555 | tic54x-*) |
1603 | os=-coff | |
1556 | os=coff | |
1604 | 1557 | ;; |
1605 | 1558 | tic55x-*) |
1606 | os=-coff | |
1559 | os=coff | |
1607 | 1560 | ;; |
1608 | 1561 | tic6x-*) |
1609 | os=-coff | |
1562 | os=coff | |
1610 | 1563 | ;; |
1611 | 1564 | # This must come before the *-dec entry. |
1612 | 1565 | pdp10-*) |
1613 | os=-tops20 | |
1566 | os=tops20 | |
1614 | 1567 | ;; |
1615 | 1568 | pdp11-*) |
1616 | os=-none | |
1569 | os=none | |
1617 | 1570 | ;; |
1618 | 1571 | *-dec | vax-*) |
1619 | os=-ultrix4.2 | |
1572 | os=ultrix4.2 | |
1620 | 1573 | ;; |
1621 | 1574 | m68*-apollo) |
1622 | os=-domain | |
1575 | os=domain | |
1623 | 1576 | ;; |
1624 | 1577 | i386-sun) |
1625 | os=-sunos4.0.2 | |
1578 | os=sunos4.0.2 | |
1626 | 1579 | ;; |
1627 | 1580 | m68000-sun) |
1628 | os=-sunos3 | |
1581 | os=sunos3 | |
1629 | 1582 | ;; |
1630 | 1583 | m68*-cisco) |
1631 | os=-aout | |
1584 | os=aout | |
1632 | 1585 | ;; |
1633 | 1586 | mep-*) |
1634 | os=-elf | |
1587 | os=elf | |
1635 | 1588 | ;; |
1636 | 1589 | mips*-cisco) |
1637 | os=-elf | |
1590 | os=elf | |
1638 | 1591 | ;; |
1639 | 1592 | mips*-*) |
1640 | os=-elf | |
1593 | os=elf | |
1641 | 1594 | ;; |
1642 | 1595 | or32-*) |
1643 | os=-coff | |
1596 | os=coff | |
1644 | 1597 | ;; |
1645 | 1598 | *-tti) # must be before sparc entry or we get the wrong os. |
1646 | os=-sysv3 | |
1599 | os=sysv3 | |
1647 | 1600 | ;; |
1648 | 1601 | sparc-* | *-sun) |
1649 | os=-sunos4.1.1 | |
1602 | os=sunos4.1.1 | |
1650 | 1603 | ;; |
1651 | 1604 | pru-*) |
1652 | os=-elf | |
1605 | os=elf | |
1653 | 1606 | ;; |
1654 | 1607 | *-be) |
1655 | os=-beos | |
1608 | os=beos | |
1656 | 1609 | ;; |
1657 | 1610 | *-ibm) |
1658 | os=-aix | |
1611 | os=aix | |
1659 | 1612 | ;; |
1660 | 1613 | *-knuth) |
1661 | os=-mmixware | |
1614 | os=mmixware | |
1662 | 1615 | ;; |
1663 | 1616 | *-wec) |
1664 | os=-proelf | |
1617 | os=proelf | |
1665 | 1618 | ;; |
1666 | 1619 | *-winbond) |
1667 | os=-proelf | |
1620 | os=proelf | |
1668 | 1621 | ;; |
1669 | 1622 | *-oki) |
1670 | os=-proelf | |
1623 | os=proelf | |
1671 | 1624 | ;; |
1672 | 1625 | *-hp) |
1673 | os=-hpux | |
1626 | os=hpux | |
1674 | 1627 | ;; |
1675 | 1628 | *-hitachi) |
1676 | os=-hiux | |
1629 | os=hiux | |
1677 | 1630 | ;; |
1678 | 1631 | i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) |
1679 | os=-sysv | |
1632 | os=sysv | |
1680 | 1633 | ;; |
1681 | 1634 | *-cbm) |
1682 | os=-amigaos | |
1635 | os=amigaos | |
1683 | 1636 | ;; |
1684 | 1637 | *-dg) |
1685 | os=-dgux | |
1638 | os=dgux | |
1686 | 1639 | ;; |
1687 | 1640 | *-dolphin) |
1688 | os=-sysv3 | |
1641 | os=sysv3 | |
1689 | 1642 | ;; |
1690 | 1643 | m68k-ccur) |
1691 | os=-rtu | |
1644 | os=rtu | |
1692 | 1645 | ;; |
1693 | 1646 | m88k-omron*) |
1694 | os=-luna | |
1647 | os=luna | |
1695 | 1648 | ;; |
1696 | 1649 | *-next) |
1697 | os=-nextstep | |
1650 | os=nextstep | |
1698 | 1651 | ;; |
1699 | 1652 | *-sequent) |
1700 | os=-ptx | |
1653 | os=ptx | |
1701 | 1654 | ;; |
1702 | 1655 | *-crds) |
1703 | os=-unos | |
1656 | os=unos | |
1704 | 1657 | ;; |
1705 | 1658 | *-ns) |
1706 | os=-genix | |
1659 | os=genix | |
1707 | 1660 | ;; |
1708 | 1661 | i370-*) |
1709 | os=-mvs | |
1662 | os=mvs | |
1710 | 1663 | ;; |
1711 | 1664 | *-gould) |
1712 | os=-sysv | |
1665 | os=sysv | |
1713 | 1666 | ;; |
1714 | 1667 | *-highlevel) |
1715 | os=-bsd | |
1668 | os=bsd | |
1716 | 1669 | ;; |
1717 | 1670 | *-encore) |
1718 | os=-bsd | |
1671 | os=bsd | |
1719 | 1672 | ;; |
1720 | 1673 | *-sgi) |
1721 | os=-irix | |
1674 | os=irix | |
1722 | 1675 | ;; |
1723 | 1676 | *-siemens) |
1724 | os=-sysv4 | |
1677 | os=sysv4 | |
1725 | 1678 | ;; |
1726 | 1679 | *-masscomp) |
1727 | os=-rtu | |
1680 | os=rtu | |
1728 | 1681 | ;; |
1729 | 1682 | f30[01]-fujitsu | f700-fujitsu) |
1730 | os=-uxpv | |
1683 | os=uxpv | |
1731 | 1684 | ;; |
1732 | 1685 | *-rom68k) |
1733 | os=-coff | |
1686 | os=coff | |
1734 | 1687 | ;; |
1735 | 1688 | *-*bug) |
1736 | os=-coff | |
1689 | os=coff | |
1737 | 1690 | ;; |
1738 | 1691 | *-apple) |
1739 | os=-macos | |
1692 | os=macos | |
1740 | 1693 | ;; |
1741 | 1694 | *-atari*) |
1742 | os=-mint | |
1695 | os=mint | |
1696 | ;; | |
1697 | *-wrs) | |
1698 | os=vxworks | |
1743 | 1699 | ;; |
1744 | 1700 | *) |
1745 | os=-none | |
1701 | os=none | |
1746 | 1702 | ;; |
1747 | 1703 | esac |
1748 | 1704 | fi |
1749 | 1705 | |
1750 | 1706 | # Here we handle the case where we know the os, and the CPU type, but not the |
1751 | 1707 | # manufacturer. We pick the logical manufacturer. |
1752 | vendor=unknown | |
1753 | case $basic_machine in | |
1754 | *-unknown) | |
1708 | case $vendor in | |
1709 | unknown) | |
1755 | 1710 | case $os in |
1756 | -riscix*) | |
1711 | riscix*) | |
1757 | 1712 | vendor=acorn |
1758 | 1713 | ;; |
1759 | -sunos*) | |
1714 | sunos*) | |
1760 | 1715 | vendor=sun |
1761 | 1716 | ;; |
1762 | -cnk*|-aix*) | |
1717 | cnk*|-aix*) | |
1763 | 1718 | vendor=ibm |
1764 | 1719 | ;; |
1765 | -beos*) | |
1720 | beos*) | |
1766 | 1721 | vendor=be |
1767 | 1722 | ;; |
1768 | -hpux*) | |
1723 | hpux*) | |
1769 | 1724 | vendor=hp |
1770 | 1725 | ;; |
1771 | -mpeix*) | |
1726 | mpeix*) | |
1772 | 1727 | vendor=hp |
1773 | 1728 | ;; |
1774 | -hiux*) | |
1729 | hiux*) | |
1775 | 1730 | vendor=hitachi |
1776 | 1731 | ;; |
1777 | -unos*) | |
1732 | unos*) | |
1778 | 1733 | vendor=crds |
1779 | 1734 | ;; |
1780 | -dgux*) | |
1735 | dgux*) | |
1781 | 1736 | vendor=dg |
1782 | 1737 | ;; |
1783 | -luna*) | |
1738 | luna*) | |
1784 | 1739 | vendor=omron |
1785 | 1740 | ;; |
1786 | -genix*) | |
1741 | genix*) | |
1787 | 1742 | vendor=ns |
1788 | 1743 | ;; |
1789 | -mvs* | -opened*) | |
1744 | clix*) | |
1745 | vendor=intergraph | |
1746 | ;; | |
1747 | mvs* | opened*) | |
1790 | 1748 | vendor=ibm |
1791 | 1749 | ;; |
1792 | -os400*) | |
1750 | os400*) | |
1793 | 1751 | vendor=ibm |
1794 | 1752 | ;; |
1795 | -ptx*) | |
1753 | ptx*) | |
1796 | 1754 | vendor=sequent |
1797 | 1755 | ;; |
1798 | -tpf*) | |
1756 | tpf*) | |
1799 | 1757 | vendor=ibm |
1800 | 1758 | ;; |
1801 | -vxsim* | -vxworks* | -windiss*) | |
1759 | vxsim* | vxworks* | windiss*) | |
1802 | 1760 | vendor=wrs |
1803 | 1761 | ;; |
1804 | -aux*) | |
1762 | aux*) | |
1805 | 1763 | vendor=apple |
1806 | 1764 | ;; |
1807 | -hms*) | |
1765 | hms*) | |
1808 | 1766 | vendor=hitachi |
1809 | 1767 | ;; |
1810 | -mpw* | -macos*) | |
1768 | mpw* | macos*) | |
1811 | 1769 | vendor=apple |
1812 | 1770 | ;; |
1813 | -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) | |
1771 | *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) | |
1814 | 1772 | vendor=atari |
1815 | 1773 | ;; |
1816 | -vos*) | |
1774 | vos*) | |
1817 | 1775 | vendor=stratus |
1818 | 1776 | ;; |
1819 | 1777 | esac |
1820 | basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` | |
1821 | 1778 | ;; |
1822 | 1779 | esac |
1823 | 1780 | |
1824 | echo "$basic_machine$os" | |
1781 | echo "$cpu-$vendor-$os" | |
1825 | 1782 | exit |
1826 | 1783 | |
1827 | 1784 | # Local variables: |
0 | 0 | #! /bin/sh |
1 | 1 | # Guess values for system-dependent variables and create Makefiles. |
2 | # Generated by GNU Autoconf 2.69 for alsa-lib 1.2.4. | |
2 | # Generated by GNU Autoconf 2.69 for alsa-lib 1.2.5.1. | |
3 | 3 | # |
4 | 4 | # |
5 | 5 | # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. |
586 | 586 | # Identity of this package. |
587 | 587 | PACKAGE_NAME='alsa-lib' |
588 | 588 | PACKAGE_TARNAME='alsa-lib' |
589 | PACKAGE_VERSION='1.2.4' | |
590 | PACKAGE_STRING='alsa-lib 1.2.4' | |
589 | PACKAGE_VERSION='1.2.5.1' | |
590 | PACKAGE_STRING='alsa-lib 1.2.5.1' | |
591 | 591 | PACKAGE_BUGREPORT='' |
592 | 592 | PACKAGE_URL='' |
593 | 593 | |
637 | 637 | BUILD_CTL_PLUGIN_EXT_TRUE |
638 | 638 | BUILD_CTL_PLUGIN_SHM_FALSE |
639 | 639 | BUILD_CTL_PLUGIN_SHM_TRUE |
640 | BUILD_CTL_PLUGIN_REMAP_FALSE | |
641 | BUILD_CTL_PLUGIN_REMAP_TRUE | |
640 | 642 | BUILD_CTL_PLUGIN_FALSE |
641 | 643 | BUILD_CTL_PLUGIN_TRUE |
642 | 644 | BUILD_PCM_PLUGIN_MMAP_EMUL_FALSE |
835 | 837 | docdir |
836 | 838 | oldincludedir |
837 | 839 | includedir |
840 | runstatedir | |
838 | 841 | localstatedir |
839 | 842 | sharedstatedir |
840 | 843 | sysconfdir |
955 | 958 | sysconfdir='${prefix}/etc' |
956 | 959 | sharedstatedir='${prefix}/com' |
957 | 960 | localstatedir='${prefix}/var' |
961 | runstatedir='${localstatedir}/run' | |
958 | 962 | includedir='${prefix}/include' |
959 | 963 | oldincludedir='/usr/include' |
960 | 964 | docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' |
1207 | 1211 | | -silent | --silent | --silen | --sile | --sil) |
1208 | 1212 | silent=yes ;; |
1209 | 1213 | |
1214 | -runstatedir | --runstatedir | --runstatedi | --runstated \ | |
1215 | | --runstate | --runstat | --runsta | --runst | --runs \ | |
1216 | | --run | --ru | --r) | |
1217 | ac_prev=runstatedir ;; | |
1218 | -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | |
1219 | | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | |
1220 | | --run=* | --ru=* | --r=*) | |
1221 | runstatedir=$ac_optarg ;; | |
1222 | ||
1210 | 1223 | -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) |
1211 | 1224 | ac_prev=sbindir ;; |
1212 | 1225 | -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ |
1344 | 1357 | for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ |
1345 | 1358 | datadir sysconfdir sharedstatedir localstatedir includedir \ |
1346 | 1359 | oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ |
1347 | libdir localedir mandir | |
1360 | libdir localedir mandir runstatedir | |
1348 | 1361 | do |
1349 | 1362 | eval ac_val=\$$ac_var |
1350 | 1363 | # Remove trailing slashes. |
1457 | 1470 | # Omit some internal or obsolete options to make the list less imposing. |
1458 | 1471 | # This message is too long to be a string in the A/UX 3.1 sh. |
1459 | 1472 | cat <<_ACEOF |
1460 | \`configure' configures alsa-lib 1.2.4 to adapt to many kinds of systems. | |
1473 | \`configure' configures alsa-lib 1.2.5.1 to adapt to many kinds of systems. | |
1461 | 1474 | |
1462 | 1475 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1463 | 1476 | |
1497 | 1510 | --sysconfdir=DIR read-only single-machine data [PREFIX/etc] |
1498 | 1511 | --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] |
1499 | 1512 | --localstatedir=DIR modifiable single-machine data [PREFIX/var] |
1513 | --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] | |
1500 | 1514 | --libdir=DIR object code libraries [EPREFIX/lib] |
1501 | 1515 | --includedir=DIR C header files [PREFIX/include] |
1502 | 1516 | --oldincludedir=DIR C header files for non-gcc [/usr/include] |
1527 | 1541 | |
1528 | 1542 | if test -n "$ac_init_help"; then |
1529 | 1543 | case $ac_init_help in |
1530 | short | recursive ) echo "Configuration of alsa-lib 1.2.4:";; | |
1544 | short | recursive ) echo "Configuration of alsa-lib 1.2.5.1:";; | |
1531 | 1545 | esac |
1532 | 1546 | cat <<\_ACEOF |
1533 | 1547 | |
1689 | 1703 | test -n "$ac_init_help" && exit $ac_status |
1690 | 1704 | if $ac_init_version; then |
1691 | 1705 | cat <<\_ACEOF |
1692 | alsa-lib configure 1.2.4 | |
1706 | alsa-lib configure 1.2.5.1 | |
1693 | 1707 | generated by GNU Autoconf 2.69 |
1694 | 1708 | |
1695 | 1709 | Copyright (C) 2012 Free Software Foundation, Inc. |
2100 | 2114 | This file contains any messages produced by compilers while |
2101 | 2115 | running configure, to aid debugging if configure makes a mistake. |
2102 | 2116 | |
2103 | It was created by alsa-lib $as_me 1.2.4, which was | |
2117 | It was created by alsa-lib $as_me 1.2.5.1, which was | |
2104 | 2118 | generated by GNU Autoconf 2.69. Invocation command line was |
2105 | 2119 | |
2106 | 2120 | $ $0 $@ |
3038 | 3052 | |
3039 | 3053 | # Define the identity of the package. |
3040 | 3054 | PACKAGE='alsa-lib' |
3041 | VERSION='1.2.4' | |
3055 | VERSION='1.2.5.1' | |
3042 | 3056 | |
3043 | 3057 | |
3044 | 3058 | cat >>confdefs.h <<_ACEOF |
12691 | 12705 | fi |
12692 | 12706 | done |
12693 | 12707 | |
12708 | for ac_func in eaccess | |
12709 | do : | |
12710 | ac_fn_c_check_func "$LINENO" "eaccess" "ac_cv_func_eaccess" | |
12711 | if test "x$ac_cv_func_eaccess" = xyes; then : | |
12712 | cat >>confdefs.h <<_ACEOF | |
12713 | #define HAVE_EACCESS 1 | |
12714 | _ACEOF | |
12715 | ||
12716 | fi | |
12717 | done | |
12718 | ||
12694 | 12719 | |
12695 | 12720 | |
12696 | 12721 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library version" >&5 |
14083 | 14108 | fi |
14084 | 14109 | |
14085 | 14110 | |
14086 | CTL_PLUGIN_LIST="shm ext" | |
14111 | CTL_PLUGIN_LIST="remap shm ext" | |
14087 | 14112 | |
14088 | 14113 | build_ctl_plugin="no" |
14089 | 14114 | for t in $CTL_PLUGIN_LIST; do |
14112 | 14137 | BUILD_CTL_PLUGIN_FALSE= |
14113 | 14138 | fi |
14114 | 14139 | |
14140 | if test x$build_ctl_remap = xyes; then | |
14141 | BUILD_CTL_PLUGIN_REMAP_TRUE= | |
14142 | BUILD_CTL_PLUGIN_REMAP_FALSE='#' | |
14143 | else | |
14144 | BUILD_CTL_PLUGIN_REMAP_TRUE='#' | |
14145 | BUILD_CTL_PLUGIN_REMAP_FALSE= | |
14146 | fi | |
14147 | ||
14115 | 14148 | if test x$build_ctl_shm = xyes; then |
14116 | 14149 | BUILD_CTL_PLUGIN_SHM_TRUE= |
14117 | 14150 | BUILD_CTL_PLUGIN_SHM_FALSE='#' |
14189 | 14222 | ln -sf . "$srcdir"/include/alsa |
14190 | 14223 | fi |
14191 | 14224 | |
14192 | ac_config_files="$ac_config_files Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg include/Makefile include/sound/Makefile include/sound/uapi/Makefile src/Versions src/Makefile src/control/Makefile src/mixer/Makefile src/pcm/Makefile src/pcm/scopes/Makefile src/rawmidi/Makefile src/timer/Makefile src/hwdep/Makefile src/seq/Makefile src/ucm/Makefile src/alisp/Makefile src/topology/Makefile src/conf/Makefile src/conf/cards/Makefile src/conf/pcm/Makefile modules/Makefile modules/mixer/Makefile modules/mixer/simple/Makefile alsalisp/Makefile aserver/Makefile test/Makefile test/lsb/Makefile utils/Makefile utils/alsa-lib.spec utils/alsa.pc utils/alsa-topology.pc" | |
14225 | ac_config_files="$ac_config_files Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg include/Makefile include/sound/Makefile include/sound/uapi/Makefile src/Versions src/Makefile src/control/Makefile src/mixer/Makefile src/pcm/Makefile src/pcm/scopes/Makefile src/rawmidi/Makefile src/timer/Makefile src/hwdep/Makefile src/seq/Makefile src/ucm/Makefile src/alisp/Makefile src/topology/Makefile src/conf/Makefile src/conf/cards/Makefile src/conf/ctl/Makefile src/conf/pcm/Makefile modules/Makefile modules/mixer/Makefile modules/mixer/simple/Makefile alsalisp/Makefile aserver/Makefile test/Makefile test/lsb/Makefile utils/Makefile utils/alsa-lib.spec utils/alsa.pc utils/alsa-topology.pc" | |
14193 | 14226 | |
14194 | 14227 | cat >confcache <<\_ACEOF |
14195 | 14228 | # This file is a shell script that caches the results of configure |
14504 | 14537 | as_fn_error $? "conditional \"BUILD_CTL_PLUGIN\" was never defined. |
14505 | 14538 | Usually this means the macro was only invoked conditionally." "$LINENO" 5 |
14506 | 14539 | fi |
14540 | if test -z "${BUILD_CTL_PLUGIN_REMAP_TRUE}" && test -z "${BUILD_CTL_PLUGIN_REMAP_FALSE}"; then | |
14541 | as_fn_error $? "conditional \"BUILD_CTL_PLUGIN_REMAP\" was never defined. | |
14542 | Usually this means the macro was only invoked conditionally." "$LINENO" 5 | |
14543 | fi | |
14507 | 14544 | if test -z "${BUILD_CTL_PLUGIN_SHM_TRUE}" && test -z "${BUILD_CTL_PLUGIN_SHM_FALSE}"; then |
14508 | 14545 | as_fn_error $? "conditional \"BUILD_CTL_PLUGIN_SHM\" was never defined. |
14509 | 14546 | Usually this means the macro was only invoked conditionally." "$LINENO" 5 |
14909 | 14946 | # report actual input values of CONFIG_FILES etc. instead of their |
14910 | 14947 | # values after options handling. |
14911 | 14948 | ac_log=" |
14912 | This file was extended by alsa-lib $as_me 1.2.4, which was | |
14949 | This file was extended by alsa-lib $as_me 1.2.5.1, which was | |
14913 | 14950 | generated by GNU Autoconf 2.69. Invocation command line was |
14914 | 14951 | |
14915 | 14952 | CONFIG_FILES = $CONFIG_FILES |
14975 | 15012 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
14976 | 15013 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" |
14977 | 15014 | ac_cs_version="\\ |
14978 | alsa-lib config.status 1.2.4 | |
15015 | alsa-lib config.status 1.2.5.1 | |
14979 | 15016 | configured by $0, generated by GNU Autoconf 2.69, |
14980 | 15017 | with options \\"\$ac_cs_config\\" |
14981 | 15018 | |
15412 | 15449 | "src/topology/Makefile") CONFIG_FILES="$CONFIG_FILES src/topology/Makefile" ;; |
15413 | 15450 | "src/conf/Makefile") CONFIG_FILES="$CONFIG_FILES src/conf/Makefile" ;; |
15414 | 15451 | "src/conf/cards/Makefile") CONFIG_FILES="$CONFIG_FILES src/conf/cards/Makefile" ;; |
15452 | "src/conf/ctl/Makefile") CONFIG_FILES="$CONFIG_FILES src/conf/ctl/Makefile" ;; | |
15415 | 15453 | "src/conf/pcm/Makefile") CONFIG_FILES="$CONFIG_FILES src/conf/pcm/Makefile" ;; |
15416 | 15454 | "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; |
15417 | 15455 | "modules/mixer/Makefile") CONFIG_FILES="$CONFIG_FILES modules/mixer/Makefile" ;; |
16101 | 16139 | { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 |
16102 | 16140 | $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} |
16103 | 16141 | as_fn_error $? "Something went wrong bootstrapping makefile fragments |
16104 | for automatic dependency tracking. Try re-running configure with the | |
16142 | for automatic dependency tracking. If GNU make was not used, consider | |
16143 | re-running the configure script with MAKE=\"gmake\" (or whatever is | |
16144 | necessary). You can also try re-running configure with the | |
16105 | 16145 | '--disable-dependency-tracking' option to at least be able to build |
16106 | 16146 | the package (albeit without support for automatic dependency tracking). |
16107 | 16147 | See \`config.log' for more details" "$LINENO" 5; } |
0 | 0 | dnl Process this file with autoconf to produce a configure script. |
1 | 1 | AC_PREREQ(2.59) |
2 | AC_INIT(alsa-lib, 1.2.4) | |
2 | AC_INIT(alsa-lib, 1.2.5.1) | |
3 | 3 | |
4 | 4 | AC_CONFIG_SRCDIR([src/control/control.c]) |
5 | 5 | AC_CONFIG_MACRO_DIR([m4]) |
49 | 49 | dnl Checks for library functions. |
50 | 50 | AC_PROG_GCC_TRADITIONAL |
51 | 51 | AC_CHECK_FUNCS([uselocale]) |
52 | AC_CHECK_FUNCS([eaccess]) | |
52 | 53 | |
53 | 54 | SAVE_LIBRARY_VERSION |
54 | 55 | AC_SUBST(LIBTOOL_VERSION_INFO) |
658 | 659 | [build control plugins (default = all)]), |
659 | 660 | [ctl_plugins="$withval"], [ctl_plugins="all"]) |
660 | 661 | |
661 | CTL_PLUGIN_LIST="shm ext" | |
662 | CTL_PLUGIN_LIST="remap shm ext" | |
662 | 663 | |
663 | 664 | build_ctl_plugin="no" |
664 | 665 | for t in $CTL_PLUGIN_LIST; do |
680 | 681 | fi |
681 | 682 | |
682 | 683 | AM_CONDITIONAL([BUILD_CTL_PLUGIN], [test x$build_ctl_plugin = xyes]) |
684 | AM_CONDITIONAL([BUILD_CTL_PLUGIN_REMAP], [test x$build_ctl_remap = xyes]) | |
683 | 685 | AM_CONDITIONAL([BUILD_CTL_PLUGIN_SHM], [test x$build_ctl_shm = xyes]) |
684 | 686 | AM_CONDITIONAL([BUILD_CTL_PLUGIN_EXT], [test x$build_ctl_ext = xyes]) |
685 | 687 | |
738 | 740 | src/alisp/Makefile src/topology/Makefile \ |
739 | 741 | src/conf/Makefile \ |
740 | 742 | src/conf/cards/Makefile \ |
743 | src/conf/ctl/Makefile \ | |
741 | 744 | src/conf/pcm/Makefile \ |
742 | 745 | modules/Makefile modules/mixer/Makefile modules/mixer/simple/Makefile \ |
743 | 746 | alsalisp/Makefile aserver/Makefile \ |
2 | 2 | |
3 | 3 | scriptversion=2018-03-07.03; # UTC |
4 | 4 | |
5 | # Copyright (C) 1999-2018 Free Software Foundation, Inc. | |
5 | # Copyright (C) 1999-2020 Free Software Foundation, Inc. | |
6 | 6 | |
7 | 7 | # This program is free software; you can redistribute it and/or modify |
8 | 8 | # it under the terms of the GNU General Public License as published by |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
304 | 304 | prefix = @prefix@ |
305 | 305 | program_transform_name = @program_transform_name@ |
306 | 306 | psdir = @psdir@ |
307 | runstatedir = @runstatedir@ | |
307 | 308 | sbindir = @sbindir@ |
308 | 309 | sharedstatedir = @sharedstatedir@ |
309 | 310 | srcdir = @srcdir@ |
39 | 39 | ../src/names.c \ |
40 | 40 | ../src/shmarea.c \ |
41 | 41 | ../src/userfile.c \ |
42 | ../src/control \ | |
42 | ../src/control/cards.c \ | |
43 | ../src/control/control.c \ | |
44 | ../src/control/control_plugin.c \ | |
45 | ../src/control/control_hw.c \ | |
46 | ../src/control/control_remap.c \ | |
47 | ../src/control/control_shm.c \ | |
48 | ../src/control/ctlparse.c \ | |
49 | ../src/control/hcontrol.c \ | |
50 | ../src/control/setup.c \ | |
51 | ../src/control/tlv.c \ | |
43 | 52 | ../src/mixer \ |
44 | 53 | ../src/pcm/pcm.c \ |
45 | 54 | ../src/pcm/pcm_mmap.c \ |
39 | 39 | @top_srcdir@/src/names.c \ |
40 | 40 | @top_srcdir@/src/shmarea.c \ |
41 | 41 | @top_srcdir@/src/userfile.c \ |
42 | @top_srcdir@/src/control \ | |
42 | @top_srcdir@/src/control/cards.c \ | |
43 | @top_srcdir@/src/control/control.c \ | |
44 | @top_srcdir@/src/control/control_plugin.c \ | |
45 | @top_srcdir@/src/control/control_hw.c \ | |
46 | @top_srcdir@/src/control/control_remap.c \ | |
47 | @top_srcdir@/src/control/control_shm.c \ | |
48 | @top_srcdir@/src/control/ctlparse.c \ | |
49 | @top_srcdir@/src/control/hcontrol.c \ | |
50 | @top_srcdir@/src/control/setup.c \ | |
51 | @top_srcdir@/src/control/tlv.c \ | |
43 | 52 | @top_srcdir@/src/mixer \ |
44 | 53 | @top_srcdir@/src/pcm/pcm.c \ |
45 | 54 | @top_srcdir@/src/pcm/pcm_mmap.c \ |
30 | 30 | |
31 | 31 | <UL> |
32 | 32 | <LI>Page \ref control explains the primitive controls API. |
33 | <LI>Page \ref control_plugins explains the design of primitive control plugins. | |
33 | 34 | <LI>Page \ref hcontrol explains the high-level primitive controls API. |
34 | 35 | <LI>Page \ref mixer explains the mixer controls API. |
35 | 36 | <LI>Page \ref pcm explains the design of the PCM (digital audio) API. |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
244 | 244 | prefix = @prefix@ |
245 | 245 | program_transform_name = @program_transform_name@ |
246 | 246 | psdir = @psdir@ |
247 | runstatedir = @runstatedir@ | |
247 | 248 | sbindir = @sbindir@ |
248 | 249 | sharedstatedir = @sharedstatedir@ |
249 | 250 | srcdir = @srcdir@ |
6 | 6 | version.h global.h input.h output.h error.h \ |
7 | 7 | conf.h control.h |
8 | 8 | |
9 | if BUILD_CTL_PLUGIN | |
10 | alsainclude_HEADERS += control_plugin.h | |
11 | endif | |
9 | 12 | if BUILD_CTL_PLUGIN_EXT |
10 | 13 | alsainclude_HEADERS += control_external.h |
11 | 14 | endif |
62 | 65 | |
63 | 66 | DISTCLEANFILES = stamp-vh version.h alsa asoundlib.h |
64 | 67 | |
65 | alsa: | |
66 | ln -s $(top_srcdir)/include alsa | |
68 | .DUMMY: alsa_link | |
69 | alsa_link: | |
70 | if ! test -r alsa/local.h; then \ | |
71 | ln -s $(top_srcdir)/include alsa; \ | |
72 | fi | |
67 | 73 | |
68 | version.h: stamp-vh alsa | |
69 | @: | |
74 | version.h: stamp-vh alsa_link | |
75 | for f in asoundlib.h version.h; do \ | |
76 | if ! test -r $(top_srcdir)/include/$$f; then \ | |
77 | ln -s $(abs_top_builddir)/include/$$f $(top_srcdir)/include/$$f; \ | |
78 | fi; \ | |
79 | done | |
70 | 80 | |
71 | 81 | stamp-vh: $(top_builddir)/configure.ac |
72 | 82 | @echo "/*" > ver.tmp |
78 | 88 | @echo "#define SND_LIB_SUBMINOR $(SND_LIB_SUBMINOR) /**< subminor number of library version */" >> ver.tmp |
79 | 89 | @echo "#define SND_LIB_EXTRAVER $(SND_LIB_EXTRAVER) /**< extra version number, used mainly for betas */" >> ver.tmp |
80 | 90 | @echo "/** library version */" >> ver.tmp |
81 | @echo "#define SND_LIB_VERSION ((SND_LIB_MAJOR<<16)|\\" >> ver.tmp | |
82 | @echo " (SND_LIB_MINOR<<8)|\\" >> ver.tmp | |
83 | @echo " SND_LIB_SUBMINOR)" >> ver.tmp | |
91 | @echo "#define SND_LIB_VER(maj, min, sub) (((maj)<<16)|((min)<<8)|(sub))" >> ver.tmp | |
92 | @echo "#define SND_LIB_VERSION SND_LIB_VER(SND_LIB_MAJOR, SND_LIB_MINOR, SND_LIB_SUBMINOR)" >> ver.tmp | |
84 | 93 | @echo "/** library version (string) */" >> ver.tmp |
85 | 94 | @echo "#define SND_LIB_VERSION_STR \"$(SND_LIB_VERSION)\"" >> ver.tmp |
86 | 95 | @echo >> ver.tmp |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
87 | 87 | POST_UNINSTALL = : |
88 | 88 | build_triplet = @build@ |
89 | 89 | host_triplet = @host@ |
90 | @BUILD_CTL_PLUGIN_EXT_TRUE@am__append_1 = control_external.h | |
91 | @BUILD_PCM_TRUE@am__append_2 = pcm.h pcm_old.h timer.h | |
92 | @BUILD_PCM_PLUGIN_TRUE@@BUILD_PCM_TRUE@am__append_3 = pcm_plugin.h | |
93 | @BUILD_PCM_PLUGIN_RATE_TRUE@@BUILD_PCM_TRUE@am__append_4 = pcm_rate.h | |
94 | @BUILD_PCM_PLUGIN_EXTPLUG_TRUE@@BUILD_PCM_TRUE@am__append_5 = pcm_external.h pcm_extplug.h | |
95 | @BUILD_PCM_PLUGIN_EXTPLUG_FALSE@@BUILD_PCM_PLUGIN_IOPLUG_TRUE@@BUILD_PCM_TRUE@am__append_6 = pcm_external.h | |
96 | @BUILD_PCM_PLUGIN_IOPLUG_TRUE@@BUILD_PCM_TRUE@am__append_7 = pcm_ioplug.h | |
97 | @BUILD_RAWMIDI_TRUE@am__append_8 = rawmidi.h | |
98 | @BUILD_HWDEP_TRUE@am__append_9 = hwdep.h | |
99 | @BUILD_MIXER_TRUE@am__append_10 = mixer.h mixer_abst.h | |
100 | @BUILD_SEQ_TRUE@am__append_11 = seq_event.h seq.h seqmid.h seq_midi_event.h | |
101 | @BUILD_UCM_TRUE@am__append_12 = use-case.h | |
102 | @BUILD_TOPOLOGY_TRUE@am__append_13 = topology.h | |
103 | @BUILD_ALISP_TRUE@am__append_14 = alisp.h | |
90 | @BUILD_CTL_PLUGIN_TRUE@am__append_1 = control_plugin.h | |
91 | @BUILD_CTL_PLUGIN_EXT_TRUE@am__append_2 = control_external.h | |
92 | @BUILD_PCM_TRUE@am__append_3 = pcm.h pcm_old.h timer.h | |
93 | @BUILD_PCM_PLUGIN_TRUE@@BUILD_PCM_TRUE@am__append_4 = pcm_plugin.h | |
94 | @BUILD_PCM_PLUGIN_RATE_TRUE@@BUILD_PCM_TRUE@am__append_5 = pcm_rate.h | |
95 | @BUILD_PCM_PLUGIN_EXTPLUG_TRUE@@BUILD_PCM_TRUE@am__append_6 = pcm_external.h pcm_extplug.h | |
96 | @BUILD_PCM_PLUGIN_EXTPLUG_FALSE@@BUILD_PCM_PLUGIN_IOPLUG_TRUE@@BUILD_PCM_TRUE@am__append_7 = pcm_external.h | |
97 | @BUILD_PCM_PLUGIN_IOPLUG_TRUE@@BUILD_PCM_TRUE@am__append_8 = pcm_ioplug.h | |
98 | @BUILD_RAWMIDI_TRUE@am__append_9 = rawmidi.h | |
99 | @BUILD_HWDEP_TRUE@am__append_10 = hwdep.h | |
100 | @BUILD_MIXER_TRUE@am__append_11 = mixer.h mixer_abst.h | |
101 | @BUILD_SEQ_TRUE@am__append_12 = seq_event.h seq.h seqmid.h seq_midi_event.h | |
102 | @BUILD_UCM_TRUE@am__append_13 = use-case.h | |
103 | @BUILD_TOPOLOGY_TRUE@am__append_14 = topology.h | |
104 | @BUILD_ALISP_TRUE@am__append_15 = alisp.h | |
104 | 105 | subdir = include |
105 | 106 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 |
106 | 107 | am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ |
145 | 146 | esac |
146 | 147 | am__alsainclude_HEADERS_DIST = asoundlib.h asoundef.h version.h \ |
147 | 148 | global.h input.h output.h error.h conf.h control.h \ |
148 | control_external.h pcm.h pcm_old.h timer.h pcm_plugin.h \ | |
149 | pcm_rate.h pcm_external.h pcm_extplug.h pcm_ioplug.h rawmidi.h \ | |
150 | hwdep.h mixer.h mixer_abst.h seq_event.h seq.h seqmid.h \ | |
151 | seq_midi_event.h use-case.h topology.h alisp.h | |
149 | control_plugin.h control_external.h pcm.h pcm_old.h timer.h \ | |
150 | pcm_plugin.h pcm_rate.h pcm_external.h pcm_extplug.h \ | |
151 | pcm_ioplug.h rawmidi.h hwdep.h mixer.h mixer_abst.h \ | |
152 | seq_event.h seq.h seqmid.h seq_midi_event.h use-case.h \ | |
153 | topology.h alisp.h | |
152 | 154 | am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; |
153 | 155 | am__vpath_adj = case $$p in \ |
154 | 156 | $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ |
186 | 188 | $(am__extra_recursive_targets) |
187 | 189 | AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ |
188 | 190 | distdir distdir-am |
189 | am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ | |
190 | $(LISP)config.h.in | |
191 | am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ | |
192 | config.h.in | |
191 | 193 | # Read a list of newline-separated strings from the standard input, |
192 | 194 | # and print each of them once, without duplicates. Input order is |
193 | 195 | # *not* preserved. |
356 | 358 | prefix = @prefix@ |
357 | 359 | program_transform_name = @program_transform_name@ |
358 | 360 | psdir = @psdir@ |
361 | runstatedir = @runstatedir@ | |
359 | 362 | sbindir = @sbindir@ |
360 | 363 | sharedstatedir = @sharedstatedir@ |
361 | 364 | srcdir = @srcdir@ |
373 | 376 | $(am__append_5) $(am__append_6) $(am__append_7) \ |
374 | 377 | $(am__append_8) $(am__append_9) $(am__append_10) \ |
375 | 378 | $(am__append_11) $(am__append_12) $(am__append_13) \ |
376 | $(am__append_14) | |
379 | $(am__append_14) $(am__append_15) | |
377 | 380 | noinst_HEADERS = alsa sys.h search.h list.h aserver.h local.h alsa-symbols.h \ |
378 | 381 | asoundlib-head.h asoundlib-tail.h bswap.h type_compat.h |
379 | 382 | |
739 | 742 | .PRECIOUS: Makefile |
740 | 743 | |
741 | 744 | |
742 | alsa: | |
743 | ln -s $(top_srcdir)/include alsa | |
744 | ||
745 | version.h: stamp-vh alsa | |
746 | @: | |
745 | .DUMMY: alsa_link | |
746 | alsa_link: | |
747 | if ! test -r alsa/local.h; then \ | |
748 | ln -s $(top_srcdir)/include alsa; \ | |
749 | fi | |
750 | ||
751 | version.h: stamp-vh alsa_link | |
752 | for f in asoundlib.h version.h; do \ | |
753 | if ! test -r $(top_srcdir)/include/$$f; then \ | |
754 | ln -s $(abs_top_builddir)/include/$$f $(top_srcdir)/include/$$f; \ | |
755 | fi; \ | |
756 | done | |
747 | 757 | |
748 | 758 | stamp-vh: $(top_builddir)/configure.ac |
749 | 759 | @echo "/*" > ver.tmp |
755 | 765 | @echo "#define SND_LIB_SUBMINOR $(SND_LIB_SUBMINOR) /**< subminor number of library version */" >> ver.tmp |
756 | 766 | @echo "#define SND_LIB_EXTRAVER $(SND_LIB_EXTRAVER) /**< extra version number, used mainly for betas */" >> ver.tmp |
757 | 767 | @echo "/** library version */" >> ver.tmp |
758 | @echo "#define SND_LIB_VERSION ((SND_LIB_MAJOR<<16)|\\" >> ver.tmp | |
759 | @echo " (SND_LIB_MINOR<<8)|\\" >> ver.tmp | |
760 | @echo " SND_LIB_SUBMINOR)" >> ver.tmp | |
768 | @echo "#define SND_LIB_VER(maj, min, sub) (((maj)<<16)|((min)<<8)|(sub))" >> ver.tmp | |
769 | @echo "#define SND_LIB_VERSION SND_LIB_VER(SND_LIB_MAJOR, SND_LIB_MINOR, SND_LIB_SUBMINOR)" >> ver.tmp | |
761 | 770 | @echo "/** library version (string) */" >> ver.tmp |
762 | 771 | @echo "#define SND_LIB_VERSION_STR \"$(SND_LIB_VERSION)\"" >> ver.tmp |
763 | 772 | @echo >> ver.tmp |
33 | 33 | #define default_symbol_version(real, name, version) \ |
34 | 34 | __asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@@" #version) |
35 | 35 | |
36 | #ifdef __clang__ | |
37 | #define EXPORT_SYMBOL __attribute__((visibility("default"))) | |
38 | #else | |
36 | 39 | #define EXPORT_SYMBOL __attribute__((visibility("default"),externally_visible)) |
40 | #endif | |
37 | 41 | |
38 | 42 | #ifdef USE_VERSIONED_SYMBOLS |
39 | 43 | #define use_symbol_version(real, name, version) \ |
120 | 120 | int snd_config_delete(snd_config_t *config); |
121 | 121 | int snd_config_delete_compound_members(const snd_config_t *config); |
122 | 122 | int snd_config_copy(snd_config_t **dst, snd_config_t *src); |
123 | int snd_config_merge(snd_config_t *dst, snd_config_t *src, int override); | |
123 | 124 | |
124 | 125 | int snd_config_make(snd_config_t **config, const char *key, |
125 | 126 | snd_config_type_t type); |
129 | 130 | int snd_config_make_string(snd_config_t **config, const char *key); |
130 | 131 | int snd_config_make_pointer(snd_config_t **config, const char *key); |
131 | 132 | int snd_config_make_compound(snd_config_t **config, const char *key, int join); |
133 | int snd_config_make_path(snd_config_t **config, snd_config_t *root, const char *key, | |
134 | int join, int override); | |
132 | 135 | |
133 | 136 | int snd_config_imake_integer(snd_config_t **config, const char *key, const long value); |
134 | 137 | int snd_config_imake_integer64(snd_config_t **config, const char *key, const long long value); |
139 | 142 | |
140 | 143 | snd_config_type_t snd_config_get_type(const snd_config_t *config); |
141 | 144 | int snd_config_is_array(const snd_config_t *config); |
145 | int snd_config_is_empty(const snd_config_t *config); | |
142 | 146 | |
143 | 147 | int snd_config_set_id(snd_config_t *config, const char *id); |
144 | 148 | int snd_config_set_integer(snd_config_t *config, long value); |
186 | 190 | |
187 | 191 | int snd_config_get_bool_ascii(const char *ascii); |
188 | 192 | int snd_config_get_bool(const snd_config_t *conf); |
193 | int snd_config_get_card(const snd_config_t *conf); | |
189 | 194 | int snd_config_get_ctl_iface_ascii(const char *ascii); |
190 | 195 | int snd_config_get_ctl_iface(const snd_config_t *conf); |
191 | 196 |
64 | 64 | |
65 | 65 | /* Define to 1 if you have the <dlfcn.h> header file. */ |
66 | 66 | #undef HAVE_DLFCN_H |
67 | ||
68 | /* Define to 1 if you have the `eaccess' function. */ | |
69 | #undef HAVE_EACCESS | |
67 | 70 | |
68 | 71 | /* Define to 1 if you have the <endian.h> header file. */ |
69 | 72 | #undef HAVE_ENDIAN_H |
311 | 311 | /** INET client CTL (not yet implemented) */ |
312 | 312 | SND_CTL_TYPE_INET, |
313 | 313 | /** External control plugin */ |
314 | SND_CTL_TYPE_EXT | |
314 | SND_CTL_TYPE_EXT, | |
315 | /** Control functionality remapping */ | |
316 | SND_CTL_TYPE_REMAP, | |
315 | 317 | } snd_ctl_type_t; |
316 | 318 | |
317 | 319 | /** Non blocking mode (flag for open mode) \hideinitializer */ |
423 | 425 | void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj); |
424 | 426 | void snd_ctl_elem_id_clear(snd_ctl_elem_id_t *obj); |
425 | 427 | void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src); |
428 | int snd_ctl_elem_id_compare_numid(const snd_ctl_elem_id_t *id1, const snd_ctl_elem_id_t *id2); | |
429 | int snd_ctl_elem_id_compare_set(const snd_ctl_elem_id_t *id1, const snd_ctl_elem_id_t *id2); | |
426 | 430 | unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj); |
427 | 431 | snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj); |
428 | 432 | unsigned int snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t *obj); |
544 | 548 | void snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t *obj, unsigned int val); |
545 | 549 | void snd_ctl_elem_info_set_name(snd_ctl_elem_info_t *obj, const char *val); |
546 | 550 | void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val); |
551 | void snd_ctl_elem_info_set_read_write(snd_ctl_elem_info_t *obj, int rval, int wval); | |
552 | void snd_ctl_elem_info_set_tlv_read_write(snd_ctl_elem_info_t *obj, int rval, int wval); | |
553 | void snd_ctl_elem_info_set_inactive(snd_ctl_elem_info_t *obj, int val); | |
547 | 554 | |
548 | 555 | int snd_ctl_add_integer_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info, |
549 | 556 | unsigned int element_count, |
0 | /** | |
1 | * \file include/control_plugin.h | |
2 | * \brief Common control plugin code | |
3 | * \author Jaroslav Kysela <perex@perex.cz> | |
4 | * \date 2021 | |
5 | * | |
6 | * Application interface library for the ALSA driver. | |
7 | * See the \ref control_plugins page for more details. | |
8 | * | |
9 | * \warning Using of contents of this header file might be dangerous | |
10 | * in the sense of compatibility reasons. The contents might be | |
11 | * freely changed in future. | |
12 | */ | |
13 | /* | |
14 | * This library is free software; you can redistribute it and/or modify | |
15 | * it under the terms of the GNU Lesser General Public License as | |
16 | * published by the Free Software Foundation; either version 2.1 of | |
17 | * the License, or (at your option) any later version. | |
18 | * | |
19 | * This program is distributed in the hope that it will be useful, | |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | * GNU Lesser General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU Lesser General Public | |
25 | * License along with this library; if not, write to the Free Software | |
26 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
27 | * | |
28 | */ | |
29 | ||
30 | #ifndef __ALSA_CONTROL_PLUGIN_H | |
31 | #define __ALSA_CONTROL_PLUGIN_H | |
32 | ||
33 | /** | |
34 | * \defgroup Control_Plugins Primitive Control Plugins | |
35 | * \ingroup Control | |
36 | * See the \ref control_plugins page for more details. | |
37 | * \{ | |
38 | */ | |
39 | ||
40 | /* | |
41 | * Control HW | |
42 | */ | |
43 | int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode); | |
44 | int _snd_ctl_hw_open(snd_ctl_t **handlep, char *name, snd_config_t *root, snd_config_t *conf, int mode); | |
45 | ||
46 | /* | |
47 | * Control Remap & Map | |
48 | */ | |
49 | int snd_ctl_remap_open(snd_ctl_t **handlep, const char *name, snd_config_t *remap, | |
50 | snd_config_t *map, snd_ctl_t *child, int mode); | |
51 | int _snd_ctl_remap_open(snd_ctl_t **handlep, char *name, snd_config_t *root, snd_config_t *conf, int mode); | |
52 | ||
53 | /** \} */ | |
54 | ||
55 | #endif /* __ALSA_CONTROL_PLUGIN_H */ |
373 | 373 | void *INTERNAL(snd_dlopen)(const char *name, int mode, char *errbuf, size_t errbuflen); |
374 | 374 | #endif |
375 | 375 | |
376 | #endif | |
376 | const char *uc_mgr_alibcfg_by_device(snd_config_t **config, const char *name); | |
377 | ||
378 | static inline int _snd_is_ucm_device(const char *name) | |
379 | { | |
380 | return name && name[0] == '_' && name[1] == 'u' && name[2] == 'c' && name[3] == 'm'; | |
381 | } | |
382 | ||
383 | #endif |
64 | 64 | int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int _close); |
65 | 65 | int snd_output_buffer_open(snd_output_t **outputp); |
66 | 66 | size_t snd_output_buffer_string(snd_output_t *output, char **buf); |
67 | size_t snd_output_buffer_steal(snd_output_t *output, char **buf); | |
67 | 68 | int snd_output_close(snd_output_t *output); |
68 | 69 | int snd_output_printf(snd_output_t *output, const char *format, ...) |
69 | 70 | #ifndef DOC_HIDDEN |
349 | 349 | SND_PCM_TSTAMP_TYPE_LAST = SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW, |
350 | 350 | } snd_pcm_tstamp_type_t; |
351 | 351 | |
352 | typedef enum _snd_pcm_audio_tstamp_type { | |
353 | /** | |
354 | * first definition for backwards compatibility only, | |
355 | * maps to wallclock/link time for HDAudio playback and DEFAULT/DMA time for everything else | |
356 | */ | |
357 | SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT = 0, | |
358 | SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT = 1, /**< DMA time, reported as per hw_ptr */ | |
359 | SND_PCM_AUDIO_TSTAMP_TYPE_LINK = 2, /**< link time reported by sample or wallclock counter, reset on startup */ | |
360 | SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE = 3, /**< link time reported by sample or wallclock counter, not reset on startup */ | |
361 | SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED = 4, /**< link time estimated indirectly */ | |
362 | SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED = 5, /**< link time synchronized with system time */ | |
363 | SND_PCM_AUDIO_TSTAMP_TYPE_LAST = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED | |
364 | } snd_pcm_audio_tstamp_type_t; | |
365 | ||
352 | 366 | typedef struct _snd_pcm_audio_tstamp_config { |
353 | 367 | /* 5 of max 16 bits used */ |
354 | 368 | unsigned int type_requested:4; |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
335 | 335 | prefix = @prefix@ |
336 | 336 | program_transform_name = @program_transform_name@ |
337 | 337 | psdir = @psdir@ |
338 | runstatedir = @runstatedir@ | |
338 | 339 | sbindir = @sbindir@ |
339 | 340 | sharedstatedir = @sharedstatedir@ |
340 | 341 | srcdir = @srcdir@ |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
293 | 293 | prefix = @prefix@ |
294 | 294 | program_transform_name = @program_transform_name@ |
295 | 295 | psdir = @psdir@ |
296 | runstatedir = @runstatedir@ | |
296 | 297 | sbindir = @sbindir@ |
297 | 298 | sharedstatedir = @sharedstatedir@ |
298 | 299 | srcdir = @srcdir@ |
168 | 168 | #define SND_SOC_TPLG_LNK_FLGBIT_VOICE_WAKEUP (1 << 3) |
169 | 169 | |
170 | 170 | /* DAI topology BCLK parameter |
171 | * For the backwards capability, by default codec is bclk master | |
172 | */ | |
173 | #define SND_SOC_TPLG_BCLK_CM 0 /* codec is bclk master */ | |
174 | #define SND_SOC_TPLG_BCLK_CS 1 /* codec is bclk slave */ | |
171 | * For the backwards capability, by default codec is bclk provider | |
172 | */ | |
173 | #define SND_SOC_TPLG_BCLK_CP 0 /* codec is bclk provider */ | |
174 | #define SND_SOC_TPLG_BCLK_CC 1 /* codec is bclk consumer */ | |
175 | /* keep previous definitions for compatibility */ | |
176 | #define SND_SOC_TPLG_BCLK_CM SND_SOC_TPLG_BCLK_CP | |
177 | #define SND_SOC_TPLG_BCLK_CS SND_SOC_TPLG_BCLK_CC | |
175 | 178 | |
176 | 179 | /* DAI topology FSYNC parameter |
177 | * For the backwards capability, by default codec is fsync master | |
178 | */ | |
179 | #define SND_SOC_TPLG_FSYNC_CM 0 /* codec is fsync master */ | |
180 | #define SND_SOC_TPLG_FSYNC_CS 1 /* codec is fsync slave */ | |
180 | * For the backwards capability, by default codec is fsync provider | |
181 | */ | |
182 | #define SND_SOC_TPLG_FSYNC_CP 0 /* codec is fsync provider */ | |
183 | #define SND_SOC_TPLG_FSYNC_CC 1 /* codec is fsync consumer */ | |
184 | /* keep previous definitions for compatibility */ | |
185 | #define SND_SOC_TPLG_FSYNC_CM SND_SOC_TPLG_FSYNC_CP | |
186 | #define SND_SOC_TPLG_FSYNC_CS SND_SOC_TPLG_FSYNC_CC | |
181 | 187 | |
182 | 188 | /* |
183 | 189 | * Block Header. |
334 | 340 | __u8 clock_gated; /* SND_SOC_TPLG_DAI_CLK_GATE_ value */ |
335 | 341 | __u8 invert_bclk; /* 1 for inverted BCLK, 0 for normal */ |
336 | 342 | __u8 invert_fsync; /* 1 for inverted frame clock, 0 for normal */ |
337 | __u8 bclk_master; /* SND_SOC_TPLG_BCLK_ value */ | |
338 | __u8 fsync_master; /* SND_SOC_TPLG_FSYNC_ value */ | |
343 | __u8 bclk_provider; /* SND_SOC_TPLG_BCLK_ value */ | |
344 | __u8 fsync_provider; /* SND_SOC_TPLG_FSYNC_ value */ | |
339 | 345 | __u8 mclk_direction; /* SND_SOC_TPLG_MCLK_ value */ |
340 | 346 | __le16 reserved; /* for 32bit alignment */ |
341 | 347 | __le32 mclk_rate; /* MCLK or SYSCLK freqency in Hz */ |
657 | 657 | * |
658 | 658 | * id "1" # used for binding to the config |
659 | 659 | * format "I2S" # physical audio format. |
660 | * bclk "master" # Platform is master of bit clock | |
661 | * fsync "slave" # Platform is slave of fsync | |
660 | * bclk "codec_provider" # Codec provides the bit clock | |
661 | * fsync "codec_consumer" # Codec follows the fsync | |
662 | 662 | * } |
663 | 663 | * </pre> |
664 | 664 | * |
1027 | 1027 | unsigned char clock_gated; /* SND_SOC_TPLG_DAI_CLK_GATE_ value */ |
1028 | 1028 | unsigned char invert_bclk; /* 1 for inverted BCLK, 0 for normal */ |
1029 | 1029 | unsigned char invert_fsync; /* 1 for inverted frame clock, 0 for normal */ |
1030 | unsigned char bclk_master; /* SND_SOC_TPLG_BCLK_ value */ | |
1031 | unsigned char fsync_master; /* SND_SOC_TPLG_FSYNC_ value */ | |
1030 | unsigned char bclk_provider; /* SND_SOC_TPLG_BCLK_ value */ | |
1031 | unsigned char fsync_provider; /* SND_SOC_TPLG_FSYNC_ value */ | |
1032 | 1032 | unsigned char mclk_direction; /* SND_SOC_TPLG_MCLK_ value */ |
1033 | 1033 | unsigned short reserved; /* for 32bit alignment */ |
1034 | 1034 | unsigned int mclk_rate; /* MCLK or SYSCLK freqency in Hz */ |
256 | 256 | * - NULL - return current card |
257 | 257 | * - _verb - return current verb |
258 | 258 | * - _file - return configuration file loaded for current card |
259 | * - _alibcfg - return private alsa-lib's configuration for current card | |
260 | * - _alibpref - return private alsa-lib's configuration device prefix for current card | |
259 | 261 | * |
260 | 262 | * - [=]{NAME}[/[{modifier}|{/device}][/{verb}]] |
261 | 263 | * - value identifier {NAME} |
417 | 419 | * \return Zero if success, otherwise a negative error code |
418 | 420 | * |
419 | 421 | * Known identifiers: |
422 | * - _fboot - execute the fixed boot sequence (value = NULL) | |
420 | 423 | * - _boot - execute the boot sequence (value = NULL) |
424 | * - only when driver controls identifiers are changed | |
425 | * (otherwise the old control values are restored) | |
421 | 426 | * - _defaults - execute the 'defaults' sequence (value = NULL) |
422 | 427 | * - _verb - set current verb = value |
423 | 428 | * - _enadev - enable given device = value |
3 | 3 | |
4 | 4 | #define SND_LIB_MAJOR 1 /**< major number of library version */ |
5 | 5 | #define SND_LIB_MINOR 2 /**< minor number of library version */ |
6 | #define SND_LIB_SUBMINOR 4 /**< subminor number of library version */ | |
6 | #define SND_LIB_SUBMINOR 5 /**< subminor number of library version */ | |
7 | 7 | #define SND_LIB_EXTRAVER 1000000 /**< extra version number, used mainly for betas */ |
8 | 8 | /** library version */ |
9 | #define SND_LIB_VERSION ((SND_LIB_MAJOR<<16)|\ | |
10 | (SND_LIB_MINOR<<8)|\ | |
11 | SND_LIB_SUBMINOR) | |
9 | #define SND_LIB_VER(maj, min, sub) (((maj)<<16)|((min)<<8)|(sub)) | |
10 | #define SND_LIB_VERSION SND_LIB_VER(SND_LIB_MAJOR, SND_LIB_MINOR, SND_LIB_SUBMINOR) | |
12 | 11 | /** library version (string) */ |
13 | #define SND_LIB_VERSION_STR "1.2.4" | |
12 | #define SND_LIB_VERSION_STR "1.2.5.1" | |
14 | 13 |
450 | 450 | trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 |
451 | 451 | |
452 | 452 | # Copy the file name to the temp name. |
453 | (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && | |
453 | (umask $cp_umask && | |
454 | { test -z "$stripcmd" || { | |
455 | # Create $dsttmp read-write so that cp doesn't create it read-only, | |
456 | # which would cause strip to fail. | |
457 | if test -z "$doit"; then | |
458 | : >"$dsttmp" # No need to fork-exec 'touch'. | |
459 | else | |
460 | $doit touch "$dsttmp" | |
461 | fi | |
462 | } | |
463 | } && | |
464 | $doit_exec $cpprog "$src" "$dsttmp") && | |
454 | 465 | |
455 | 466 | # and set any options; do chmod last to preserve setuid bits. |
456 | 467 | # |
0 | 0 | #! /bin/sh |
1 | # Generated automatically by config.status (alsa-lib) 1.2.4 | |
2 | # Libtool was configured on host e010f88cea4a: | |
1 | # Generated automatically by config.status (alsa-lib) 1.2.5.1 | |
2 | # Libtool was configured on host 68d9557a10be: | |
3 | 3 | # NOTE: Changes made to this file will be lost: look at ltmain.sh. |
4 | 4 | |
5 | 5 | # Provide generalized library-building support services. |
281 | 281 | hardcode_into_libs=yes |
282 | 282 | |
283 | 283 | # Compile-time system search path for libraries. |
284 | sys_lib_search_path_spec="/usr/lib/gcc/x86_64-redhat-linux/8 /usr/lib64 /lib64 /usr/lib /lib " | |
284 | sys_lib_search_path_spec="/usr/lib/gcc/x86_64-redhat-linux/11 /usr/lib64 /lib64 /usr/lib /lib " | |
285 | 285 | |
286 | 286 | # Detected run-time system search path for libraries. |
287 | 287 | sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib /usr/lib64/qt-3.3/lib " |
2 | 2 | |
3 | 3 | scriptversion=2018-03-07.03; # UTC |
4 | 4 | |
5 | # Copyright (C) 1996-2018 Free Software Foundation, Inc. | |
5 | # Copyright (C) 1996-2020 Free Software Foundation, Inc. | |
6 | 6 | # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. |
7 | 7 | |
8 | 8 | # This program is free software; you can redistribute it and/or modify |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
304 | 304 | prefix = @prefix@ |
305 | 305 | program_transform_name = @program_transform_name@ |
306 | 306 | psdir = @psdir@ |
307 | runstatedir = @runstatedir@ | |
307 | 308 | sbindir = @sbindir@ |
308 | 309 | sharedstatedir = @sharedstatedir@ |
309 | 310 | srcdir = @srcdir@ |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
304 | 304 | prefix = @prefix@ |
305 | 305 | program_transform_name = @program_transform_name@ |
306 | 306 | psdir = @psdir@ |
307 | runstatedir = @runstatedir@ | |
307 | 308 | sbindir = @sbindir@ |
308 | 309 | sharedstatedir = @sharedstatedir@ |
309 | 310 | srcdir = @srcdir@ |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
367 | 367 | prefix = @prefix@ |
368 | 368 | program_transform_name = @program_transform_name@ |
369 | 369 | psdir = @psdir@ |
370 | runstatedir = @runstatedir@ | |
370 | 371 | sbindir = @sbindir@ |
371 | 372 | sharedstatedir = @sharedstatedir@ |
372 | 373 | srcdir = @srcdir@ |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
392 | 392 | prefix = @prefix@ |
393 | 393 | program_transform_name = @program_transform_name@ |
394 | 394 | psdir = @psdir@ |
395 | runstatedir = @runstatedir@ | |
395 | 396 | sbindir = @sbindir@ |
396 | 397 | sharedstatedir = @sharedstatedir@ |
397 | 398 | srcdir = @srcdir@ |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
295 | 295 | prefix = @prefix@ |
296 | 296 | program_transform_name = @program_transform_name@ |
297 | 297 | psdir = @psdir@ |
298 | runstatedir = @runstatedir@ | |
298 | 299 | sbindir = @sbindir@ |
299 | 300 | sharedstatedir = @sharedstatedir@ |
300 | 301 | srcdir = @srcdir@ |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
336 | 336 | prefix = @prefix@ |
337 | 337 | program_transform_name = @program_transform_name@ |
338 | 338 | psdir = @psdir@ |
339 | runstatedir = @runstatedir@ | |
339 | 340 | sbindir = @sbindir@ |
340 | 341 | sharedstatedir = @sharedstatedir@ |
341 | 342 | srcdir = @srcdir@ |
344 | 345 | top_build_prefix = @top_build_prefix@ |
345 | 346 | top_builddir = @top_builddir@ |
346 | 347 | top_srcdir = @top_srcdir@ |
347 | SUBDIRS = cards pcm | |
348 | SUBDIRS = cards ctl pcm | |
348 | 349 | cfg_files = alsa.conf $(am__append_1) $(am__append_2) |
349 | 350 | EXTRA_DIST = $(cfg_files) |
350 | 351 | alsaconfigdir = @ALSA_CONFIG_DIR@ |
7 | 7 | { |
8 | 8 | func load |
9 | 9 | files [ |
10 | "/var/lib/alsa/conf.d" | |
10 | 11 | "/usr/etc/alsa/conf.d" |
11 | 12 | "/etc/alsa/conf.d" |
12 | 13 | "/etc/asound.conf|||/usr/etc/asound.conf" |
56 | 57 | ".conf" |
57 | 58 | ] |
58 | 59 | } |
60 | { | |
61 | root { | |
62 | @func private_integer | |
63 | } | |
64 | file { | |
65 | @func concat | |
66 | strings [ | |
67 | "/var/lib/alsa/card" | |
68 | { @func private_integer } | |
69 | ".conf.d" | |
70 | ] | |
71 | } | |
72 | } | |
59 | 73 | ] |
74 | table { | |
75 | id { | |
76 | @func concat | |
77 | strings [ | |
78 | { @func private_integer } | |
79 | ] | |
80 | } | |
81 | value { | |
82 | @func concat | |
83 | strings [ | |
84 | "cards." | |
85 | { @func private_string } | |
86 | ] | |
87 | } | |
88 | } | |
60 | 89 | errors false |
61 | 90 | } |
62 | 91 | ] |
340 | 369 | # Control interface |
341 | 370 | # |
342 | 371 | |
343 | ctl.sysdefault { | |
344 | type hw | |
345 | card { | |
346 | @func getenv | |
347 | vars [ | |
348 | ALSA_CTL_CARD | |
349 | ALSA_CARD | |
350 | ] | |
351 | default { | |
352 | @func refer | |
353 | name defaults.ctl.card | |
354 | } | |
355 | } | |
356 | hint.description "Default control device" | |
357 | } | |
358 | ctl.default ctl.sysdefault | |
372 | ctl.default cards.ctl.default | |
373 | ctl.sysdefault cards.ctl.default | |
359 | 374 | |
360 | 375 | ctl.hw { |
361 | 376 | @args [ CARD ] |
397 | 397 | } |
398 | 398 | } |
399 | 399 | |
400 | HDA-Intel.pcm.hdmi.8 { | |
401 | @args [ CARD AES0 AES1 AES2 AES3 ] | |
402 | @args.CARD { type string } | |
403 | @args.AES0 { type integer } | |
404 | @args.AES1 { type integer } | |
405 | @args.AES2 { type integer } | |
406 | @args.AES3 { type integer } | |
407 | @func refer | |
408 | name { | |
409 | @func concat | |
410 | strings [ | |
411 | "cards.HDA-Intel.pcm.hdmi.common:" | |
412 | "CARD=" $CARD "," | |
413 | "DEVICE=14," | |
414 | "CTLINDEX=8," | |
415 | "AES0=" $AES0 "," | |
416 | "AES1=" $AES1 "," | |
417 | "AES2=" $AES2 "," | |
418 | "AES3=" $AES3 | |
419 | ] | |
420 | } | |
421 | } | |
422 | ||
423 | HDA-Intel.pcm.hdmi.9 { | |
424 | @args [ CARD AES0 AES1 AES2 AES3 ] | |
425 | @args.CARD { type string } | |
426 | @args.AES0 { type integer } | |
427 | @args.AES1 { type integer } | |
428 | @args.AES2 { type integer } | |
429 | @args.AES3 { type integer } | |
430 | @func refer | |
431 | name { | |
432 | @func concat | |
433 | strings [ | |
434 | "cards.HDA-Intel.pcm.hdmi.common:" | |
435 | "CARD=" $CARD "," | |
436 | "DEVICE=15," | |
437 | "CTLINDEX=9," | |
438 | "AES0=" $AES0 "," | |
439 | "AES1=" $AES1 "," | |
440 | "AES2=" $AES2 "," | |
441 | "AES3=" $AES3 | |
442 | ] | |
443 | } | |
444 | } | |
445 | ||
446 | HDA-Intel.pcm.hdmi.10 { | |
447 | @args [ CARD AES0 AES1 AES2 AES3 ] | |
448 | @args.CARD { type string } | |
449 | @args.AES0 { type integer } | |
450 | @args.AES1 { type integer } | |
451 | @args.AES2 { type integer } | |
452 | @args.AES3 { type integer } | |
453 | @func refer | |
454 | name { | |
455 | @func concat | |
456 | strings [ | |
457 | "cards.HDA-Intel.pcm.hdmi.common:" | |
458 | "CARD=" $CARD "," | |
459 | "DEVICE=16," | |
460 | "CTLINDEX=10," | |
461 | "AES0=" $AES0 "," | |
462 | "AES1=" $AES1 "," | |
463 | "AES2=" $AES2 "," | |
464 | "AES3=" $AES3 | |
465 | ] | |
466 | } | |
467 | } | |
468 | ||
400 | 469 | <confdir:pcm/modem.conf> |
401 | 470 | |
402 | 471 | HDA-Intel.pcm.modem.0 { |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
275 | 275 | prefix = @prefix@ |
276 | 276 | program_transform_name = @program_transform_name@ |
277 | 277 | psdir = @psdir@ |
278 | runstatedir = @runstatedir@ | |
278 | 279 | sbindir = @sbindir@ |
279 | 280 | sharedstatedir = @sharedstatedir@ |
280 | 281 | srcdir = @srcdir@ |
37 | 37 | USB-Audio.pcm.iec958_device { |
38 | 38 | # "NoiseBlaster 3000" 42 |
39 | 39 | "USB Sound Blaster HD" 1 |
40 | "SB Omni Surround 5.1" 1 | |
41 | ||
40 | 42 | "Xonar U7" 1 |
43 | "Xonar U7 MKII" 1 | |
41 | 44 | "ASUS XONAR U5" 1 |
42 | 45 | "XONAR U5" 1 |
43 | 46 | "XONAR SOUND CARD" 1 |
47 | 50 | "Andrea PureAudio USB-SA Headset" 999 |
48 | 51 | "Blue Snowball" 999 |
49 | 52 | "C-Media USB Headphone Set" 999 |
53 | "Cmedia Audio" 999 | |
54 | "DELL PROFESSIONAL SOUND BAR AE5" 999 | |
50 | 55 | "HP Digital Stereo Headset" 999 |
51 | 56 | "GN 9330" 999 |
52 | 57 | "Logitech Speaker Lapdesk N700" 999 |
54 | 59 | "Logitech USB Headset" 999 |
55 | 60 | "Logitech USB Headset H540" 999 |
56 | 61 | "Logitech Wireless Headset" 999 |
62 | "Plantronics Blackwire 3220 Seri" 999 | |
57 | 63 | "Plantronics GameCom 780" 999 |
58 | 64 | "Plantronics USB Headset" 999 |
59 | 65 | "Plantronics Wireless Audio" 999 |
57 | 57 | pistachio cards.pistachio-card |
58 | 58 | VC4-HDMI cards.vc4-hdmi |
59 | 59 | |
60 | <confdir:ctl/default.conf> | |
60 | 61 | <confdir:pcm/default.conf> |
61 | 62 | <confdir:pcm/dmix.conf> |
62 | 63 | <confdir:pcm/dsnoop.conf> |
0 | cfg_files = default.conf | |
1 | ||
2 | EXTRA_DIST = $(cfg_files) | |
3 | ||
4 | alsaconfigdir = @ALSA_CONFIG_DIR@ | |
5 | alsadir = $(alsaconfigdir)/ctl | |
6 | alsa_DATA = $(cfg_files) |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | # @configure_input@ | |
2 | ||
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | ||
5 | # This Makefile.in is free software; the Free Software Foundation | |
6 | # gives unlimited permission to copy and/or distribute it, | |
7 | # with or without modifications, as long as this notice is preserved. | |
8 | ||
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without | |
11 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
12 | # PARTICULAR PURPOSE. | |
13 | ||
14 | @SET_MAKE@ | |
15 | ||
16 | VPATH = @srcdir@ | |
17 | am__is_gnu_make = { \ | |
18 | if test -z '$(MAKELEVEL)'; then \ | |
19 | false; \ | |
20 | elif test -n '$(MAKE_HOST)'; then \ | |
21 | true; \ | |
22 | elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ | |
23 | true; \ | |
24 | else \ | |
25 | false; \ | |
26 | fi; \ | |
27 | } | |
28 | am__make_running_with_option = \ | |
29 | case $${target_option-} in \ | |
30 | ?) ;; \ | |
31 | *) echo "am__make_running_with_option: internal error: invalid" \ | |
32 | "target option '$${target_option-}' specified" >&2; \ | |
33 | exit 1;; \ | |
34 | esac; \ | |
35 | has_opt=no; \ | |
36 | sane_makeflags=$$MAKEFLAGS; \ | |
37 | if $(am__is_gnu_make); then \ | |
38 | sane_makeflags=$$MFLAGS; \ | |
39 | else \ | |
40 | case $$MAKEFLAGS in \ | |
41 | *\\[\ \ ]*) \ | |
42 | bs=\\; \ | |
43 | sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | |
44 | | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ | |
45 | esac; \ | |
46 | fi; \ | |
47 | skip_next=no; \ | |
48 | strip_trailopt () \ | |
49 | { \ | |
50 | flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ | |
51 | }; \ | |
52 | for flg in $$sane_makeflags; do \ | |
53 | test $$skip_next = yes && { skip_next=no; continue; }; \ | |
54 | case $$flg in \ | |
55 | *=*|--*) continue;; \ | |
56 | -*I) strip_trailopt 'I'; skip_next=yes;; \ | |
57 | -*I?*) strip_trailopt 'I';; \ | |
58 | -*O) strip_trailopt 'O'; skip_next=yes;; \ | |
59 | -*O?*) strip_trailopt 'O';; \ | |
60 | -*l) strip_trailopt 'l'; skip_next=yes;; \ | |
61 | -*l?*) strip_trailopt 'l';; \ | |
62 | -[dEDm]) skip_next=yes;; \ | |
63 | -[JT]) skip_next=yes;; \ | |
64 | esac; \ | |
65 | case $$flg in \ | |
66 | *$$target_option*) has_opt=yes; break;; \ | |
67 | esac; \ | |
68 | done; \ | |
69 | test $$has_opt = yes | |
70 | am__make_dryrun = (target_option=n; $(am__make_running_with_option)) | |
71 | am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) | |
72 | pkgdatadir = $(datadir)/@PACKAGE@ | |
73 | pkgincludedir = $(includedir)/@PACKAGE@ | |
74 | pkglibdir = $(libdir)/@PACKAGE@ | |
75 | pkglibexecdir = $(libexecdir)/@PACKAGE@ | |
76 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd | |
77 | install_sh_DATA = $(install_sh) -c -m 644 | |
78 | install_sh_PROGRAM = $(install_sh) -c | |
79 | install_sh_SCRIPT = $(install_sh) -c | |
80 | INSTALL_HEADER = $(INSTALL_DATA) | |
81 | transform = $(program_transform_name) | |
82 | NORMAL_INSTALL = : | |
83 | PRE_INSTALL = : | |
84 | POST_INSTALL = : | |
85 | NORMAL_UNINSTALL = : | |
86 | PRE_UNINSTALL = : | |
87 | POST_UNINSTALL = : | |
88 | build_triplet = @build@ | |
89 | host_triplet = @host@ | |
90 | subdir = src/conf/ctl | |
91 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | |
92 | am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ | |
93 | $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ | |
94 | $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ | |
95 | $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \ | |
96 | $(top_srcdir)/configure.ac | |
97 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ | |
98 | $(ACLOCAL_M4) | |
99 | DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) | |
100 | mkinstalldirs = $(install_sh) -d | |
101 | CONFIG_HEADER = $(top_builddir)/include/config.h | |
102 | CONFIG_CLEAN_FILES = | |
103 | CONFIG_CLEAN_VPATH_FILES = | |
104 | AM_V_P = $(am__v_P_@AM_V@) | |
105 | am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) | |
106 | am__v_P_0 = false | |
107 | am__v_P_1 = : | |
108 | AM_V_GEN = $(am__v_GEN_@AM_V@) | |
109 | am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) | |
110 | am__v_GEN_0 = @echo " GEN " $@; | |
111 | am__v_GEN_1 = | |
112 | AM_V_at = $(am__v_at_@AM_V@) | |
113 | am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) | |
114 | am__v_at_0 = @ | |
115 | am__v_at_1 = | |
116 | SOURCES = | |
117 | DIST_SOURCES = | |
118 | am__can_run_installinfo = \ | |
119 | case $$AM_UPDATE_INFO_DIR in \ | |
120 | n|no|NO) false;; \ | |
121 | *) (install-info --version) >/dev/null 2>&1;; \ | |
122 | esac | |
123 | am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; | |
124 | am__vpath_adj = case $$p in \ | |
125 | $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ | |
126 | *) f=$$p;; \ | |
127 | esac; | |
128 | am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; | |
129 | am__install_max = 40 | |
130 | am__nobase_strip_setup = \ | |
131 | srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` | |
132 | am__nobase_strip = \ | |
133 | for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" | |
134 | am__nobase_list = $(am__nobase_strip_setup); \ | |
135 | for p in $$list; do echo "$$p $$p"; done | \ | |
136 | sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ | |
137 | $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ | |
138 | if (++n[$$2] == $(am__install_max)) \ | |
139 | { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ | |
140 | END { for (dir in files) print dir, files[dir] }' | |
141 | am__base_list = \ | |
142 | sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ | |
143 | sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | |
144 | am__uninstall_files_from_dir = { \ | |
145 | test -z "$$files" \ | |
146 | || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ | |
147 | || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ | |
148 | $(am__cd) "$$dir" && rm -f $$files; }; \ | |
149 | } | |
150 | am__installdirs = "$(DESTDIR)$(alsadir)" | |
151 | DATA = $(alsa_DATA) | |
152 | am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) | |
153 | am__DIST_COMMON = $(srcdir)/Makefile.in | |
154 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) | |
155 | ACLOCAL = @ACLOCAL@ | |
156 | ALSA_CONFIG_DIR = @ALSA_CONFIG_DIR@ | |
157 | ALSA_DEPLIBS = @ALSA_DEPLIBS@ | |
158 | ALSA_PKGCONF_DIR = @ALSA_PKGCONF_DIR@ | |
159 | ALSA_PLUGIN_DIR = @ALSA_PLUGIN_DIR@ | |
160 | AMTAR = @AMTAR@ | |
161 | AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ | |
162 | AR = @AR@ | |
163 | AUTOCONF = @AUTOCONF@ | |
164 | AUTOHEADER = @AUTOHEADER@ | |
165 | AUTOMAKE = @AUTOMAKE@ | |
166 | AWK = @AWK@ | |
167 | CC = @CC@ | |
168 | CCDEPMODE = @CCDEPMODE@ | |
169 | CFLAGS = @CFLAGS@ | |
170 | CPP = @CPP@ | |
171 | CPPFLAGS = @CPPFLAGS@ | |
172 | CYGPATH_W = @CYGPATH_W@ | |
173 | DEFS = @DEFS@ | |
174 | DEPDIR = @DEPDIR@ | |
175 | DLLTOOL = @DLLTOOL@ | |
176 | DSYMUTIL = @DSYMUTIL@ | |
177 | DUMPBIN = @DUMPBIN@ | |
178 | ECHO_C = @ECHO_C@ | |
179 | ECHO_N = @ECHO_N@ | |
180 | ECHO_T = @ECHO_T@ | |
181 | EGREP = @EGREP@ | |
182 | EXEEXT = @EXEEXT@ | |
183 | FGREP = @FGREP@ | |
184 | GREP = @GREP@ | |
185 | INSTALL = @INSTALL@ | |
186 | INSTALL_DATA = @INSTALL_DATA@ | |
187 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ | |
188 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ | |
189 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ | |
190 | LD = @LD@ | |
191 | LDFLAGS = @LDFLAGS@ | |
192 | LDFLAGS_NOUNDEFINED = @LDFLAGS_NOUNDEFINED@ | |
193 | LIBOBJS = @LIBOBJS@ | |
194 | LIBS = @LIBS@ | |
195 | LIBTOOL = @LIBTOOL@ | |
196 | LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@ | |
197 | LIPO = @LIPO@ | |
198 | LN_S = @LN_S@ | |
199 | LTLIBOBJS = @LTLIBOBJS@ | |
200 | LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ | |
201 | MAINT = @MAINT@ | |
202 | MAKEINFO = @MAKEINFO@ | |
203 | MANIFEST_TOOL = @MANIFEST_TOOL@ | |
204 | MKDIR_P = @MKDIR_P@ | |
205 | NM = @NM@ | |
206 | NMEDIT = @NMEDIT@ | |
207 | OBJDUMP = @OBJDUMP@ | |
208 | OBJEXT = @OBJEXT@ | |
209 | OTOOL = @OTOOL@ | |
210 | OTOOL64 = @OTOOL64@ | |
211 | PACKAGE = @PACKAGE@ | |
212 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ | |
213 | PACKAGE_NAME = @PACKAGE_NAME@ | |
214 | PACKAGE_STRING = @PACKAGE_STRING@ | |
215 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ | |
216 | PACKAGE_URL = @PACKAGE_URL@ | |
217 | PACKAGE_VERSION = @PACKAGE_VERSION@ | |
218 | PATH_SEPARATOR = @PATH_SEPARATOR@ | |
219 | PYTHON_INCLUDES = @PYTHON_INCLUDES@ | |
220 | PYTHON_LIBS = @PYTHON_LIBS@ | |
221 | RANLIB = @RANLIB@ | |
222 | SED = @SED@ | |
223 | SET_MAKE = @SET_MAKE@ | |
224 | SHELL = @SHELL@ | |
225 | SND_LIB_EXTRAVER = @SND_LIB_EXTRAVER@ | |
226 | SND_LIB_MAJOR = @SND_LIB_MAJOR@ | |
227 | SND_LIB_MINOR = @SND_LIB_MINOR@ | |
228 | SND_LIB_SUBMINOR = @SND_LIB_SUBMINOR@ | |
229 | SND_LIB_VERSION = @SND_LIB_VERSION@ | |
230 | STRIP = @STRIP@ | |
231 | SYMBOL_PREFIX = @SYMBOL_PREFIX@ | |
232 | VERSION = @VERSION@ | |
233 | abs_builddir = @abs_builddir@ | |
234 | abs_srcdir = @abs_srcdir@ | |
235 | abs_top_builddir = @abs_top_builddir@ | |
236 | abs_top_srcdir = @abs_top_srcdir@ | |
237 | ac_ct_AR = @ac_ct_AR@ | |
238 | ac_ct_CC = @ac_ct_CC@ | |
239 | ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ | |
240 | am__include = @am__include@ | |
241 | am__leading_dot = @am__leading_dot@ | |
242 | am__quote = @am__quote@ | |
243 | am__tar = @am__tar@ | |
244 | am__untar = @am__untar@ | |
245 | bindir = @bindir@ | |
246 | build = @build@ | |
247 | build_alias = @build_alias@ | |
248 | build_cpu = @build_cpu@ | |
249 | build_os = @build_os@ | |
250 | build_vendor = @build_vendor@ | |
251 | builddir = @builddir@ | |
252 | datadir = @datadir@ | |
253 | datarootdir = @datarootdir@ | |
254 | docdir = @docdir@ | |
255 | dvidir = @dvidir@ | |
256 | exec_prefix = @exec_prefix@ | |
257 | host = @host@ | |
258 | host_alias = @host_alias@ | |
259 | host_cpu = @host_cpu@ | |
260 | host_os = @host_os@ | |
261 | host_vendor = @host_vendor@ | |
262 | htmldir = @htmldir@ | |
263 | includedir = @includedir@ | |
264 | infodir = @infodir@ | |
265 | install_sh = @install_sh@ | |
266 | libdir = @libdir@ | |
267 | libexecdir = @libexecdir@ | |
268 | localedir = @localedir@ | |
269 | localstatedir = @localstatedir@ | |
270 | mandir = @mandir@ | |
271 | mkdir_p = @mkdir_p@ | |
272 | oldincludedir = @oldincludedir@ | |
273 | pdfdir = @pdfdir@ | |
274 | prefix = @prefix@ | |
275 | program_transform_name = @program_transform_name@ | |
276 | psdir = @psdir@ | |
277 | runstatedir = @runstatedir@ | |
278 | sbindir = @sbindir@ | |
279 | sharedstatedir = @sharedstatedir@ | |
280 | srcdir = @srcdir@ | |
281 | sysconfdir = @sysconfdir@ | |
282 | target_alias = @target_alias@ | |
283 | top_build_prefix = @top_build_prefix@ | |
284 | top_builddir = @top_builddir@ | |
285 | top_srcdir = @top_srcdir@ | |
286 | cfg_files = default.conf | |
287 | EXTRA_DIST = $(cfg_files) | |
288 | alsaconfigdir = @ALSA_CONFIG_DIR@ | |
289 | alsadir = $(alsaconfigdir)/ctl | |
290 | alsa_DATA = $(cfg_files) | |
291 | all: all-am | |
292 | ||
293 | .SUFFIXES: | |
294 | $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) | |
295 | @for dep in $?; do \ | |
296 | case '$(am__configure_deps)' in \ | |
297 | *$$dep*) \ | |
298 | ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ | |
299 | && { if test -f $@; then exit 0; else break; fi; }; \ | |
300 | exit 1;; \ | |
301 | esac; \ | |
302 | done; \ | |
303 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/conf/ctl/Makefile'; \ | |
304 | $(am__cd) $(top_srcdir) && \ | |
305 | $(AUTOMAKE) --foreign src/conf/ctl/Makefile | |
306 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status | |
307 | @case '$?' in \ | |
308 | *config.status*) \ | |
309 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ | |
310 | *) \ | |
311 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ | |
312 | cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ | |
313 | esac; | |
314 | ||
315 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) | |
316 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | |
317 | ||
318 | $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) | |
319 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | |
320 | $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) | |
321 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | |
322 | $(am__aclocal_m4_deps): | |
323 | ||
324 | mostlyclean-libtool: | |
325 | -rm -f *.lo | |
326 | ||
327 | clean-libtool: | |
328 | -rm -rf .libs _libs | |
329 | install-alsaDATA: $(alsa_DATA) | |
330 | @$(NORMAL_INSTALL) | |
331 | @list='$(alsa_DATA)'; test -n "$(alsadir)" || list=; \ | |
332 | if test -n "$$list"; then \ | |
333 | echo " $(MKDIR_P) '$(DESTDIR)$(alsadir)'"; \ | |
334 | $(MKDIR_P) "$(DESTDIR)$(alsadir)" || exit 1; \ | |
335 | fi; \ | |
336 | for p in $$list; do \ | |
337 | if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ | |
338 | echo "$$d$$p"; \ | |
339 | done | $(am__base_list) | \ | |
340 | while read files; do \ | |
341 | echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(alsadir)'"; \ | |
342 | $(INSTALL_DATA) $$files "$(DESTDIR)$(alsadir)" || exit $$?; \ | |
343 | done | |
344 | ||
345 | uninstall-alsaDATA: | |
346 | @$(NORMAL_UNINSTALL) | |
347 | @list='$(alsa_DATA)'; test -n "$(alsadir)" || list=; \ | |
348 | files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ | |
349 | dir='$(DESTDIR)$(alsadir)'; $(am__uninstall_files_from_dir) | |
350 | tags TAGS: | |
351 | ||
352 | ctags CTAGS: | |
353 | ||
354 | cscope cscopelist: | |
355 | ||
356 | ||
357 | distdir: $(BUILT_SOURCES) | |
358 | $(MAKE) $(AM_MAKEFLAGS) distdir-am | |
359 | ||
360 | distdir-am: $(DISTFILES) | |
361 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | |
362 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | |
363 | list='$(DISTFILES)'; \ | |
364 | dist_files=`for file in $$list; do echo $$file; done | \ | |
365 | sed -e "s|^$$srcdirstrip/||;t" \ | |
366 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ | |
367 | case $$dist_files in \ | |
368 | */*) $(MKDIR_P) `echo "$$dist_files" | \ | |
369 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ | |
370 | sort -u` ;; \ | |
371 | esac; \ | |
372 | for file in $$dist_files; do \ | |
373 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ | |
374 | if test -d $$d/$$file; then \ | |
375 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ | |
376 | if test -d "$(distdir)/$$file"; then \ | |
377 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ | |
378 | fi; \ | |
379 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ | |
380 | cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ | |
381 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ | |
382 | fi; \ | |
383 | cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ | |
384 | else \ | |
385 | test -f "$(distdir)/$$file" \ | |
386 | || cp -p $$d/$$file "$(distdir)/$$file" \ | |
387 | || exit 1; \ | |
388 | fi; \ | |
389 | done | |
390 | check-am: all-am | |
391 | check: check-am | |
392 | all-am: Makefile $(DATA) | |
393 | installdirs: | |
394 | for dir in "$(DESTDIR)$(alsadir)"; do \ | |
395 | test -z "$$dir" || $(MKDIR_P) "$$dir"; \ | |
396 | done | |
397 | install: install-am | |
398 | install-exec: install-exec-am | |
399 | install-data: install-data-am | |
400 | uninstall: uninstall-am | |
401 | ||
402 | install-am: all-am | |
403 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | |
404 | ||
405 | installcheck: installcheck-am | |
406 | install-strip: | |
407 | if test -z '$(STRIP)'; then \ | |
408 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ | |
409 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ | |
410 | install; \ | |
411 | else \ | |
412 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ | |
413 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ | |
414 | "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ | |
415 | fi | |
416 | mostlyclean-generic: | |
417 | ||
418 | clean-generic: | |
419 | ||
420 | distclean-generic: | |
421 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) | |
422 | -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) | |
423 | ||
424 | maintainer-clean-generic: | |
425 | @echo "This command is intended for maintainers to use" | |
426 | @echo "it deletes files that may require special tools to rebuild." | |
427 | clean: clean-am | |
428 | ||
429 | clean-am: clean-generic clean-libtool mostlyclean-am | |
430 | ||
431 | distclean: distclean-am | |
432 | -rm -f Makefile | |
433 | distclean-am: clean-am distclean-generic | |
434 | ||
435 | dvi: dvi-am | |
436 | ||
437 | dvi-am: | |
438 | ||
439 | html: html-am | |
440 | ||
441 | html-am: | |
442 | ||
443 | info: info-am | |
444 | ||
445 | info-am: | |
446 | ||
447 | install-data-am: install-alsaDATA | |
448 | ||
449 | install-dvi: install-dvi-am | |
450 | ||
451 | install-dvi-am: | |
452 | ||
453 | install-exec-am: | |
454 | ||
455 | install-html: install-html-am | |
456 | ||
457 | install-html-am: | |
458 | ||
459 | install-info: install-info-am | |
460 | ||
461 | install-info-am: | |
462 | ||
463 | install-man: | |
464 | ||
465 | install-pdf: install-pdf-am | |
466 | ||
467 | install-pdf-am: | |
468 | ||
469 | install-ps: install-ps-am | |
470 | ||
471 | install-ps-am: | |
472 | ||
473 | installcheck-am: | |
474 | ||
475 | maintainer-clean: maintainer-clean-am | |
476 | -rm -f Makefile | |
477 | maintainer-clean-am: distclean-am maintainer-clean-generic | |
478 | ||
479 | mostlyclean: mostlyclean-am | |
480 | ||
481 | mostlyclean-am: mostlyclean-generic mostlyclean-libtool | |
482 | ||
483 | pdf: pdf-am | |
484 | ||
485 | pdf-am: | |
486 | ||
487 | ps: ps-am | |
488 | ||
489 | ps-am: | |
490 | ||
491 | uninstall-am: uninstall-alsaDATA | |
492 | ||
493 | .MAKE: install-am install-strip | |
494 | ||
495 | .PHONY: all all-am check check-am clean clean-generic clean-libtool \ | |
496 | cscopelist-am ctags-am distclean distclean-generic \ | |
497 | distclean-libtool distdir dvi dvi-am html html-am info info-am \ | |
498 | install install-alsaDATA install-am install-data \ | |
499 | install-data-am install-dvi install-dvi-am install-exec \ | |
500 | install-exec-am install-html install-html-am install-info \ | |
501 | install-info-am install-man install-pdf install-pdf-am \ | |
502 | install-ps install-ps-am install-strip installcheck \ | |
503 | installcheck-am installdirs maintainer-clean \ | |
504 | maintainer-clean-generic mostlyclean mostlyclean-generic \ | |
505 | mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ | |
506 | uninstall-alsaDATA uninstall-am | |
507 | ||
508 | .PRECIOUS: Makefile | |
509 | ||
510 | ||
511 | # Tell versions [3.59,3.63) of GNU make to not export all variables. | |
512 | # Otherwise a system limit (for SysV at least) may be exceeded. | |
513 | .NOEXPORT: |
0 | # | |
1 | # Default control device | |
2 | # | |
3 | ||
4 | ctl.!default { | |
5 | @args [ CARD ] | |
6 | @args.CARD { | |
7 | type string | |
8 | default { | |
9 | @func getenv | |
10 | vars [ | |
11 | ALSA_PCM_CARD | |
12 | ALSA_CARD | |
13 | ] | |
14 | default { | |
15 | @func refer | |
16 | name defaults.ctl.card | |
17 | } | |
18 | } | |
19 | } | |
20 | type empty | |
21 | child { | |
22 | # use card-specific definition if exists | |
23 | @func refer | |
24 | name { | |
25 | @func concat | |
26 | strings [ | |
27 | "cards." | |
28 | { | |
29 | @func card_inum | |
30 | card $CARD | |
31 | } | |
32 | ".ctl.default:CARD=" $CARD | |
33 | ] | |
34 | } | |
35 | default { | |
36 | type hw | |
37 | card $CARD | |
38 | } | |
39 | } | |
40 | hint.description "Default Control Device" | |
41 | } |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
274 | 274 | prefix = @prefix@ |
275 | 275 | program_transform_name = @program_transform_name@ |
276 | 276 | psdir = @psdir@ |
277 | runstatedir = @runstatedir@ | |
277 | 278 | sbindir = @sbindir@ |
278 | 279 | sharedstatedir = @sharedstatedir@ |
279 | 280 | srcdir = @srcdir@ |
39 | 39 | strings [ |
40 | 40 | "cards." |
41 | 41 | { |
42 | @func card_driver | |
42 | @func card_inum | |
43 | 43 | card $CARD |
44 | 44 | } |
45 | 45 | ".pcm.center_lfe." $DEV ":CARD=" $CARD |
26 | 26 | strings [ |
27 | 27 | "cards." |
28 | 28 | { |
29 | @func card_driver | |
29 | @func card_inum | |
30 | 30 | card $CARD |
31 | 31 | } |
32 | 32 | ".pcm.default:CARD=" $CARD |
76 | 76 | strings [ |
77 | 77 | "defaults.dmix." |
78 | 78 | { |
79 | @func card_driver | |
79 | @func card_id | |
80 | 80 | card $CARD |
81 | 81 | } |
82 | 82 | ".period_size" |
91 | 91 | strings [ |
92 | 92 | "defaults.dmix." |
93 | 93 | { |
94 | @func card_driver | |
94 | @func card_id | |
95 | 95 | card $CARD |
96 | 96 | } |
97 | 97 | ".period_time" |
106 | 106 | strings [ |
107 | 107 | "defaults.dmix." |
108 | 108 | { |
109 | @func card_driver | |
109 | @func card_id | |
110 | 110 | card $CARD |
111 | 111 | } |
112 | 112 | ".periods" |
68 | 68 | strings [ |
69 | 69 | "cards." |
70 | 70 | { |
71 | @func card_driver | |
71 | @func card_id | |
72 | 72 | card $CARD |
73 | 73 | } |
74 | 74 | ".pcm.dsnoop.period_size" |
83 | 83 | strings [ |
84 | 84 | "cards." |
85 | 85 | { |
86 | @func card_driver | |
86 | @func card_id | |
87 | 87 | card $CARD |
88 | 88 | } |
89 | 89 | ".pcm.dsnoop.period_time" |
98 | 98 | strings [ |
99 | 99 | "cards." |
100 | 100 | { |
101 | @func card_driver | |
101 | @func card_id | |
102 | 102 | card $CARD |
103 | 103 | } |
104 | 104 | ".pcm.dsnoop.periods" |
39 | 39 | strings [ |
40 | 40 | "cards." |
41 | 41 | { |
42 | @func card_driver | |
42 | @func card_inum | |
43 | 43 | card $CARD |
44 | 44 | } |
45 | 45 | ".pcm.front." $DEV ":CARD=" $CARD |
59 | 59 | strings [ |
60 | 60 | "cards." |
61 | 61 | { |
62 | @func card_driver | |
62 | @func card_inum | |
63 | 63 | card $CARD |
64 | 64 | } |
65 | 65 | ".pcm.hdmi." $DEV ":" |
59 | 59 | strings [ |
60 | 60 | "cards." |
61 | 61 | { |
62 | @func card_driver | |
62 | @func card_inum | |
63 | 63 | card $CARD |
64 | 64 | } |
65 | 65 | ".pcm.iec958." $DEV ":" |
37 | 37 | strings [ |
38 | 38 | "cards." |
39 | 39 | { |
40 | @func card_driver | |
40 | @func card_inum | |
41 | 41 | card $CARD |
42 | 42 | } |
43 | 43 | ".pcm.modem." $DEV ":CARD=" $CARD |
39 | 39 | strings [ |
40 | 40 | "cards." |
41 | 41 | { |
42 | @func card_driver | |
42 | @func card_inum | |
43 | 43 | card $CARD |
44 | 44 | } |
45 | 45 | ".pcm.rear." $DEV ":CARD=" $CARD |
39 | 39 | strings [ |
40 | 40 | "cards." |
41 | 41 | { |
42 | @func card_driver | |
42 | @func card_inum | |
43 | 43 | card $CARD |
44 | 44 | } |
45 | 45 | ".pcm.side." $DEV ":CARD=" $CARD |
43 | 43 | strings [ |
44 | 44 | "cards." |
45 | 45 | { |
46 | @func card_driver | |
46 | @func card_inum | |
47 | 47 | card $CARD |
48 | 48 | } |
49 | 49 | ".pcm.surround51." $DEV ":CARD=" $CARD |
44 | 44 | strings [ |
45 | 45 | "cards." |
46 | 46 | { |
47 | @func card_driver | |
47 | @func card_inum | |
48 | 48 | card $CARD |
49 | 49 | } |
50 | 50 | ".pcm.surround40." $DEV ":CARD=" $CARD |
45 | 45 | strings [ |
46 | 46 | "cards." |
47 | 47 | { |
48 | @func card_driver | |
48 | @func card_inum | |
49 | 49 | card $CARD |
50 | 50 | } |
51 | 51 | ".pcm.surround51." $DEV ":CARD=" $CARD |
45 | 45 | strings [ |
46 | 46 | "cards." |
47 | 47 | { |
48 | @func card_driver | |
48 | @func card_inum | |
49 | 49 | card $CARD |
50 | 50 | } |
51 | 51 | ".pcm.surround51." $DEV ":CARD=" $CARD |
46 | 46 | strings [ |
47 | 47 | "cards." |
48 | 48 | { |
49 | @func card_driver | |
49 | @func card_inum | |
50 | 50 | card $CARD |
51 | 51 | } |
52 | 52 | ".pcm.surround51." $DEV ":CARD=" $CARD |
48 | 48 | strings [ |
49 | 49 | "cards." |
50 | 50 | { |
51 | @func card_driver | |
51 | @func card_inum | |
52 | 52 | card $CARD |
53 | 53 | } |
54 | 54 | ".pcm.surround71." $DEV ":CARD=" $CARD |
886 | 886 | if (c >= '0' && c <= '9') num |= (c - '0') << 0; |
887 | 887 | else if (c >= 'a' && c <= 'f') num |= (c - 'a') << 0; |
888 | 888 | else if (c >= 'A' && c <= 'F') num |= (c - 'A') << 0; |
889 | return c; | |
889 | return num; | |
890 | 890 | } |
891 | 891 | |
892 | 892 | static int get_quotedchar(input_t *input) |
1507 | 1507 | |
1508 | 1508 | static void string_print(char *str, int id, snd_output_t *out) |
1509 | 1509 | { |
1510 | int q; | |
1510 | 1511 | unsigned char *p = (unsigned char *)str; |
1511 | 1512 | if (!p || !*p) { |
1512 | 1513 | snd_output_puts(out, "''"); |
1548 | 1549 | snd_output_puts(out, str); |
1549 | 1550 | return; |
1550 | 1551 | quoted: |
1551 | snd_output_putc(out, '\''); | |
1552 | q = strchr(str, '\'') ? '"' : '\''; | |
1553 | snd_output_putc(out, q); | |
1552 | 1554 | p = (unsigned char *)str; |
1553 | 1555 | while (*p) { |
1554 | 1556 | int c; |
1578 | 1580 | snd_output_putc(out, '\\'); |
1579 | 1581 | snd_output_putc(out, 'f'); |
1580 | 1582 | break; |
1581 | case '\'': | |
1582 | snd_output_putc(out, '\\'); | |
1583 | snd_output_putc(out, c); | |
1583 | default: | |
1584 | if (c == q) { | |
1585 | snd_output_putc(out, '\\'); | |
1586 | snd_output_putc(out, c); | |
1587 | } else { | |
1588 | if (c >= 32 && c <= 126) | |
1589 | snd_output_putc(out, c); | |
1590 | else | |
1591 | snd_output_printf(out, "\\%04o", c); | |
1592 | } | |
1584 | 1593 | break; |
1585 | default: | |
1586 | if (c >= 32 && c <= 126 && c != '\'') | |
1587 | snd_output_putc(out, c); | |
1588 | else | |
1589 | snd_output_printf(out, "\\%04o", c); | |
1590 | break; | |
1591 | 1594 | } |
1592 | 1595 | p++; |
1593 | 1596 | } |
1594 | snd_output_putc(out, '\''); | |
1597 | snd_output_putc(out, q); | |
1598 | } | |
1599 | ||
1600 | static void level_print(snd_output_t *out, unsigned int level) | |
1601 | { | |
1602 | char a[level + 1]; | |
1603 | memset(a, '\t', level); | |
1604 | a[level] = '\0'; | |
1605 | snd_output_puts(out, a); | |
1595 | 1606 | } |
1596 | 1607 | |
1597 | 1608 | static int _snd_config_save_children(snd_config_t *config, snd_output_t *out, |
1598 | unsigned int level, unsigned int joins); | |
1599 | ||
1600 | static int _snd_config_save_node_value(snd_config_t *n, snd_output_t *out, | |
1601 | unsigned int level) | |
1602 | { | |
1603 | int err; | |
1604 | unsigned int k; | |
1609 | unsigned int level, unsigned int joins, | |
1610 | int array); | |
1611 | ||
1612 | int _snd_config_save_node_value(snd_config_t *n, snd_output_t *out, | |
1613 | unsigned int level) | |
1614 | { | |
1615 | int err, array; | |
1605 | 1616 | switch (n->type) { |
1606 | 1617 | case SND_CONFIG_TYPE_INTEGER: |
1607 | 1618 | snd_output_printf(out, "%ld", n->u.integer); |
1619 | 1630 | SNDERR("cannot save runtime pointer type"); |
1620 | 1631 | return -EINVAL; |
1621 | 1632 | case SND_CONFIG_TYPE_COMPOUND: |
1622 | snd_output_putc(out, '{'); | |
1633 | array = snd_config_is_array(n); | |
1634 | snd_output_putc(out, array ? '[' : '{'); | |
1623 | 1635 | snd_output_putc(out, '\n'); |
1624 | err = _snd_config_save_children(n, out, level + 1, 0); | |
1636 | err = _snd_config_save_children(n, out, level + 1, 0, array); | |
1625 | 1637 | if (err < 0) |
1626 | 1638 | return err; |
1627 | for (k = 0; k < level; ++k) { | |
1628 | snd_output_putc(out, '\t'); | |
1629 | } | |
1630 | snd_output_putc(out, '}'); | |
1639 | level_print(out, level); | |
1640 | snd_output_putc(out, array ? ']' : '}'); | |
1631 | 1641 | break; |
1632 | 1642 | } |
1633 | 1643 | return 0; |
1644 | 1654 | } |
1645 | 1655 | |
1646 | 1656 | static int _snd_config_save_children(snd_config_t *config, snd_output_t *out, |
1647 | unsigned int level, unsigned int joins) | |
1648 | { | |
1649 | unsigned int k; | |
1657 | unsigned int level, unsigned int joins, | |
1658 | int array) | |
1659 | { | |
1650 | 1660 | int err; |
1651 | 1661 | snd_config_iterator_t i, next; |
1652 | 1662 | assert(config && out); |
1654 | 1664 | snd_config_t *n = snd_config_iterator_entry(i); |
1655 | 1665 | if (n->type == SND_CONFIG_TYPE_COMPOUND && |
1656 | 1666 | n->u.compound.join) { |
1657 | err = _snd_config_save_children(n, out, level, joins + 1); | |
1667 | err = _snd_config_save_children(n, out, level, joins + 1, 0); | |
1658 | 1668 | if (err < 0) |
1659 | 1669 | return err; |
1660 | 1670 | continue; |
1661 | 1671 | } |
1662 | for (k = 0; k < level; ++k) { | |
1663 | snd_output_putc(out, '\t'); | |
1664 | } | |
1665 | id_print(n, out, joins); | |
1672 | level_print(out, level); | |
1673 | if (!array) { | |
1674 | id_print(n, out, joins); | |
1675 | snd_output_putc(out, ' '); | |
1666 | 1676 | #if 0 |
1667 | snd_output_putc(out, ' '); | |
1668 | snd_output_putc(out, '='); | |
1677 | snd_output_putc(out, '='); | |
1669 | 1678 | #endif |
1670 | snd_output_putc(out, ' '); | |
1679 | } | |
1671 | 1680 | err = _snd_config_save_node_value(n, out, level); |
1672 | 1681 | if (err < 0) |
1673 | 1682 | return err; |
1687 | 1696 | * \param src Handle to the source node. Must not be the same as \a dst. |
1688 | 1697 | * \return Zero if successful, otherwise a negative error code. |
1689 | 1698 | * |
1690 | * If both nodes are compounds, the source compound node members are | |
1691 | * appended to the destination compound node. | |
1699 | * If both nodes are compounds, the source compound node members will | |
1700 | * be moved to the destination compound node. The original destination | |
1701 | * compound node members will be deleted (overwritten). | |
1692 | 1702 | * |
1693 | 1703 | * If the destination node is a compound and the source node is |
1694 | 1704 | * an ordinary type, the compound members are deleted (including |
1703 | 1713 | int snd_config_substitute(snd_config_t *dst, snd_config_t *src) |
1704 | 1714 | { |
1705 | 1715 | assert(dst && src); |
1716 | if (dst->type == SND_CONFIG_TYPE_COMPOUND) { | |
1717 | int err = snd_config_delete_compound_members(dst); | |
1718 | if (err < 0) | |
1719 | return err; | |
1720 | } | |
1706 | 1721 | if (dst->type == SND_CONFIG_TYPE_COMPOUND && |
1707 | src->type == SND_CONFIG_TYPE_COMPOUND) { /* append */ | |
1722 | src->type == SND_CONFIG_TYPE_COMPOUND) { /* overwrite */ | |
1708 | 1723 | snd_config_iterator_t i, next; |
1709 | 1724 | snd_config_for_each(i, next, src) { |
1710 | 1725 | snd_config_t *n = snd_config_iterator_entry(i); |
1712 | 1727 | } |
1713 | 1728 | src->u.compound.fields.next->prev = &dst->u.compound.fields; |
1714 | 1729 | src->u.compound.fields.prev->next = &dst->u.compound.fields; |
1715 | } else if (dst->type == SND_CONFIG_TYPE_COMPOUND) { | |
1716 | int err; | |
1717 | err = snd_config_delete_compound_members(dst); | |
1718 | if (err < 0) | |
1719 | return err; | |
1720 | 1730 | } |
1721 | 1731 | free(dst->id); |
1722 | 1732 | dst->id = src->id; |
1801 | 1811 | } |
1802 | 1812 | |
1803 | 1813 | /** |
1804 | * \brief Returns if the compound is an array. | |
1814 | * \brief Returns if the compound is an array (and count of items). | |
1805 | 1815 | * \param config Handle to the configuration node. |
1806 | * \return A positive value when true, zero when false, otherwise a negative error code. | |
1816 | * \return A count of items in array, zero when the compound is not an array, | |
1817 | * otherwise a negative error code. | |
1807 | 1818 | */ |
1808 | 1819 | int snd_config_is_array(const snd_config_t *config) |
1809 | 1820 | { |
1821 | 1832 | return 0; |
1822 | 1833 | idx++; |
1823 | 1834 | } |
1824 | return 1; | |
1835 | return idx; | |
1836 | } | |
1837 | ||
1838 | /** | |
1839 | * \brief Returns if the compound has no fields (is empty). | |
1840 | * \param config Handle to the configuration node. | |
1841 | * \return A positive value when true, zero when false, otherwise a negative error code. | |
1842 | */ | |
1843 | int snd_config_is_empty(const snd_config_t *config) | |
1844 | { | |
1845 | assert(config); | |
1846 | if (config->type != SND_CONFIG_TYPE_COMPOUND) | |
1847 | return -EINVAL; | |
1848 | return list_empty(&config->u.compound.fields); | |
1825 | 1849 | } |
1826 | 1850 | |
1827 | 1851 | /** |
1969 | 1993 | SNDERR("%s:%d:%d:%s", fd->name ? fd->name : "_toplevel_", fd->line, fd->column, str); |
1970 | 1994 | goto _end; |
1971 | 1995 | } |
1972 | if (get_char(&input) != LOCAL_UNEXPECTED_EOF) { | |
1996 | err = get_char(&input); | |
1997 | fd = input.current; | |
1998 | if (err != LOCAL_UNEXPECTED_EOF) { | |
1973 | 1999 | SNDERR("%s:%d:%d:Unexpected }", fd->name ? fd->name : "", fd->line, fd->column); |
1974 | 2000 | err = -EINVAL; |
1975 | 2001 | goto _end; |
1976 | 2002 | } |
2003 | err = 0; | |
1977 | 2004 | _end: |
1978 | 2005 | while (fd->next) { |
1979 | 2006 | fd_next = fd->next; |
2145 | 2172 | } |
2146 | 2173 | child->parent = parent; |
2147 | 2174 | list_insert(&child->list, before->list.prev, &before->list); |
2175 | return 0; | |
2176 | } | |
2177 | ||
2178 | /* | |
2179 | * append all src items to the end of dst arrray | |
2180 | */ | |
2181 | static int _snd_config_array_merge(snd_config_t *dst, snd_config_t *src, int index) | |
2182 | { | |
2183 | snd_config_iterator_t si, snext; | |
2184 | int err; | |
2185 | ||
2186 | snd_config_for_each(si, snext, src) { | |
2187 | snd_config_t *sn = snd_config_iterator_entry(si); | |
2188 | char id[16]; | |
2189 | snd_config_remove(sn); | |
2190 | snprintf(id, sizeof(id), "%d", index++); | |
2191 | err = snd_config_set_id(sn, id); | |
2192 | if (err < 0) { | |
2193 | snd_config_delete(sn); | |
2194 | return err; | |
2195 | } | |
2196 | sn->parent = dst; | |
2197 | list_add_tail(&sn->list, &dst->u.compound.fields); | |
2198 | } | |
2199 | snd_config_delete(src); | |
2200 | return 0; | |
2201 | } | |
2202 | ||
2203 | /** | |
2204 | * \brief In-place merge of two config handles | |
2205 | * \param dst[out] Config handle for the merged contents | |
2206 | * \param src[in] Config handle to merge into dst (may be NULL) | |
2207 | * \param override[in] Override flag | |
2208 | * \return Zero if successful, otherwise a negative error code. | |
2209 | * | |
2210 | * This function merges all fields from the source compound to the destination compound. | |
2211 | * When the \a override flag is set, the related subtree in \a dst is replaced from \a src. | |
2212 | * | |
2213 | * When \a override is not set, the child compounds are traversed and merged. | |
2214 | * | |
2215 | * The configuration elements other than compounds are always substituted (overwritten) | |
2216 | * from the \a src config handle. | |
2217 | * | |
2218 | * The src handle is deleted. | |
2219 | * | |
2220 | * Note: On error, config handles may be modified. | |
2221 | * | |
2222 | * \par Errors: | |
2223 | * <dl> | |
2224 | * <dt>-EEXIST<dd>identifier already exists (!overwrite) | |
2225 | * <dt>-ENOMEM<dd>not enough memory | |
2226 | * </dl> | |
2227 | */ | |
2228 | int snd_config_merge(snd_config_t *dst, snd_config_t *src, int override) | |
2229 | { | |
2230 | snd_config_iterator_t di, si, dnext, snext; | |
2231 | bool found; | |
2232 | int err, array; | |
2233 | ||
2234 | assert(dst); | |
2235 | if (src == NULL) | |
2236 | return 0; | |
2237 | if (dst->type != SND_CONFIG_TYPE_COMPOUND || src->type != SND_CONFIG_TYPE_COMPOUND) | |
2238 | return snd_config_substitute(dst, src); | |
2239 | array = snd_config_is_array(dst); | |
2240 | if (array && snd_config_is_array(src)) | |
2241 | return _snd_config_array_merge(dst, src, array); | |
2242 | snd_config_for_each(si, snext, src) { | |
2243 | snd_config_t *sn = snd_config_iterator_entry(si); | |
2244 | found = false; | |
2245 | snd_config_for_each(di, dnext, dst) { | |
2246 | snd_config_t *dn = snd_config_iterator_entry(di); | |
2247 | if (strcmp(sn->id, dn->id) == 0) { | |
2248 | if (override || | |
2249 | sn->type != SND_CONFIG_TYPE_COMPOUND || | |
2250 | dn->type != SND_CONFIG_TYPE_COMPOUND) { | |
2251 | snd_config_remove(sn); | |
2252 | err = snd_config_substitute(dn, sn); | |
2253 | if (err < 0) | |
2254 | return err; | |
2255 | } else { | |
2256 | err = snd_config_merge(dn, sn, 0); | |
2257 | if (err < 0) | |
2258 | return err; | |
2259 | } | |
2260 | found = true; | |
2261 | break; | |
2262 | } | |
2263 | } | |
2264 | if (!found) { | |
2265 | /* move config from src to dst */ | |
2266 | snd_config_remove(sn); | |
2267 | sn->parent = dst; | |
2268 | list_add_tail(&sn->list, &dst->u.compound.fields); | |
2269 | } | |
2270 | } | |
2271 | snd_config_delete(src); | |
2148 | 2272 | return 0; |
2149 | 2273 | } |
2150 | 2274 | |
2465 | 2589 | return err; |
2466 | 2590 | (*config)->u.compound.join = join; |
2467 | 2591 | return 0; |
2592 | } | |
2593 | ||
2594 | /** | |
2595 | * \brief Creates an empty compound configuration node in the path. | |
2596 | * \param[out] config The function puts the handle to the new or | |
2597 | * existing compound node at the address specified | |
2598 | * by \a config. | |
2599 | * \param[in] root The id of the new node. | |
2600 | * \param[in] key The id of the new node. | |
2601 | * \param[in] join Join flag. | |
2602 | * \param[in] override Override flag. | |
2603 | * \return Zero if successful, otherwise a negative error code. | |
2604 | * | |
2605 | * This function creates a new empty node of type | |
2606 | * #SND_CONFIG_TYPE_COMPOUND if the path does not exist. Otherwise, | |
2607 | * the node from the current configuration tree is returned without | |
2608 | * any modification. The \a join argument is ignored in this case. | |
2609 | * | |
2610 | * \a join determines how the compound node's id is printed when the | |
2611 | * configuration is saved to a text file. For example, if the join flag | |
2612 | * of compound node \c a is zero, the output will look as follows: | |
2613 | * \code | |
2614 | * a { | |
2615 | * b "hello" | |
2616 | * c 42 | |
2617 | * } | |
2618 | * \endcode | |
2619 | * If, however, the join flag of \c a is nonzero, its id will be joined | |
2620 | * with its children's ids, like this: | |
2621 | * \code | |
2622 | * a.b "hello" | |
2623 | * a.c 42 | |
2624 | * \endcode | |
2625 | * An \e empty compound node with its join flag set would result in no | |
2626 | * output, i.e., after saving and reloading the configuration file, that | |
2627 | * compound node would be lost. | |
2628 | * | |
2629 | * \par Errors: | |
2630 | * <dl> | |
2631 | * <dt>-ENOMEM<dd>Out of memory. | |
2632 | * <dt>-EACCESS<dd>Path exists, but it's not a compound (!override) | |
2633 | * </dl> | |
2634 | */ | |
2635 | int snd_config_make_path(snd_config_t **config, snd_config_t *root, | |
2636 | const char *key, int join, int override) | |
2637 | { | |
2638 | snd_config_t *n; | |
2639 | const char *p; | |
2640 | int err; | |
2641 | ||
2642 | while (1) { | |
2643 | p = strchr(key, '.'); | |
2644 | if (p) { | |
2645 | err = _snd_config_search(root, key, p - key, &n); | |
2646 | if (err < 0) { | |
2647 | size_t l = p - key; | |
2648 | char *s = malloc(l + 1); | |
2649 | if (s == NULL) | |
2650 | return -ENOMEM; | |
2651 | strncpy(s, key, l); | |
2652 | s[l] = '\0'; | |
2653 | err = snd_config_make_compound(&n, s, join); | |
2654 | free(s); | |
2655 | if (err < 0) | |
2656 | return err; | |
2657 | err = snd_config_add(root, n); | |
2658 | if (err < 0) | |
2659 | return err; | |
2660 | } | |
2661 | root = n; | |
2662 | key = p + 1; | |
2663 | } else { | |
2664 | err = _snd_config_search(root, key, -1, config); | |
2665 | if (err == 0) { | |
2666 | if ((*config)->type != SND_CONFIG_TYPE_COMPOUND) { | |
2667 | if (override) { | |
2668 | err = snd_config_delete(*config); | |
2669 | if (err < 0) | |
2670 | return err; | |
2671 | goto __make; | |
2672 | } else { | |
2673 | return -EACCES; | |
2674 | } | |
2675 | } | |
2676 | return 0; | |
2677 | } | |
2678 | __make: | |
2679 | err = snd_config_make_compound(&n, key, join); | |
2680 | if (err < 0) | |
2681 | return err; | |
2682 | err = snd_config_add(root, n); | |
2683 | if (err < 0) | |
2684 | return err; | |
2685 | *config = n; | |
2686 | return 0; | |
2687 | } | |
2688 | } | |
2468 | 2689 | } |
2469 | 2690 | |
2470 | 2691 | /** |
3123 | 3344 | int snd_config_save(snd_config_t *config, snd_output_t *out) |
3124 | 3345 | { |
3125 | 3346 | assert(config && out); |
3126 | if (config->type == SND_CONFIG_TYPE_COMPOUND) | |
3127 | return _snd_config_save_children(config, out, 0, 0); | |
3128 | else | |
3347 | if (config->type == SND_CONFIG_TYPE_COMPOUND) { | |
3348 | int array = snd_config_is_array(config); | |
3349 | return _snd_config_save_children(config, out, 0, 0, array); | |
3350 | } else { | |
3129 | 3351 | return _snd_config_save_node_value(config, out, 0); |
3352 | } | |
3130 | 3353 | } |
3131 | 3354 | |
3132 | 3355 | /* |
3877 | 4100 | return err; |
3878 | 4101 | } |
3879 | 4102 | |
4103 | static int config_file_load_user_all(snd_config_t *_root, snd_config_t *_file, int errors) | |
4104 | { | |
4105 | snd_config_t *file = _file, *root = _root, *n; | |
4106 | char *name, *name2, *remain, *rname = NULL; | |
4107 | int err; | |
4108 | ||
4109 | if (snd_config_get_type(_file) == SND_CONFIG_TYPE_COMPOUND) { | |
4110 | if ((err = snd_config_search(_file, "file", &file)) < 0) { | |
4111 | SNDERR("Field file not found"); | |
4112 | return err; | |
4113 | } | |
4114 | if ((err = snd_config_search(_file, "root", &root)) >= 0) { | |
4115 | err = snd_config_get_ascii(root, &rname); | |
4116 | if (err < 0) { | |
4117 | SNDERR("Field root is bad"); | |
4118 | return err; | |
4119 | } | |
4120 | err = snd_config_make_compound(&root, rname, 0); | |
4121 | if (err < 0) | |
4122 | return err; | |
4123 | } | |
4124 | } | |
4125 | if ((err = snd_config_get_ascii(file, &name)) < 0) | |
4126 | goto _err; | |
4127 | name2 = name; | |
4128 | remain = strstr(name, "|||"); | |
4129 | while (1) { | |
4130 | if (remain) { | |
4131 | *remain = '\0'; | |
4132 | remain += 3; | |
4133 | } | |
4134 | err = config_file_load_user(root, name2, errors); | |
4135 | if (err < 0) | |
4136 | goto _err; | |
4137 | if (err == 0) /* first hit wins */ | |
4138 | break; | |
4139 | if (!remain) | |
4140 | break; | |
4141 | name2 = remain; | |
4142 | remain = strstr(remain, "|||"); | |
4143 | } | |
4144 | _err: | |
4145 | if (root != _root) { | |
4146 | if (err == 0) { | |
4147 | if (snd_config_get_type(root) == SND_CONFIG_TYPE_COMPOUND) { | |
4148 | if (snd_config_is_empty(root)) | |
4149 | goto _del; | |
4150 | } | |
4151 | err = snd_config_make_path(&n, _root, rname, 0, 1); | |
4152 | if (err < 0) | |
4153 | goto _del; | |
4154 | err = snd_config_substitute(n, root); | |
4155 | if (err == 0) | |
4156 | goto _fin; | |
4157 | } | |
4158 | _del: | |
4159 | snd_config_delete(root); | |
4160 | } | |
4161 | _fin: | |
4162 | free(name); | |
4163 | free(rname); | |
4164 | return err; | |
4165 | } | |
4166 | ||
3880 | 4167 | /** |
3881 | 4168 | * \brief Loads and parses the given configurations files. |
3882 | 4169 | * \param[in] root Handle to the root configuration node. |
3897 | 4184 | |
3898 | 4185 | assert(root && dst); |
3899 | 4186 | if ((err = snd_config_search(config, "errors", &n)) >= 0) { |
3900 | char *tmp; | |
3901 | err = snd_config_get_ascii(n, &tmp); | |
3902 | if (err < 0) | |
3903 | return err; | |
3904 | errors = snd_config_get_bool_ascii(tmp); | |
3905 | free(tmp); | |
4187 | errors = snd_config_get_bool(n); | |
3906 | 4188 | if (errors < 0) { |
3907 | 4189 | SNDERR("Invalid bool value in field errors"); |
3908 | 4190 | return errors; |
3933 | 4215 | goto _err; |
3934 | 4216 | } |
3935 | 4217 | if (i == idx) { |
3936 | char *name, *name2, *remain; | |
3937 | if ((err = snd_config_get_ascii(n, &name)) < 0) | |
4218 | err = config_file_load_user_all(root, n, errors); | |
4219 | if (err < 0) | |
3938 | 4220 | goto _err; |
3939 | name2 = name; | |
3940 | remain = strstr(name, "|||"); | |
3941 | while (1) { | |
3942 | if (remain) { | |
3943 | *remain = '\0'; | |
3944 | remain += 3; | |
3945 | } | |
3946 | err = config_file_load_user(root, name2, errors); | |
3947 | if (err < 0) | |
3948 | goto _err; | |
3949 | if (err == 0) /* first hit wins */ | |
3950 | break; | |
3951 | if (!remain) | |
3952 | break; | |
3953 | name2 = remain; | |
3954 | remain = strstr(remain, "|||"); | |
3955 | } | |
3956 | free(name); | |
3957 | 4221 | idx++; |
3958 | 4222 | hit = 1; |
3959 | 4223 | } |
3972 | 4236 | #ifndef DOC_HIDDEN |
3973 | 4237 | int snd_determine_driver(int card, char **driver); |
3974 | 4238 | #endif |
4239 | ||
4240 | snd_config_t *_snd_config_hook_private_data(int card, const char *driver) | |
4241 | { | |
4242 | snd_config_t *private_data, *v; | |
4243 | int err; | |
4244 | ||
4245 | err = snd_config_make_compound(&private_data, NULL, 0); | |
4246 | if (err < 0) | |
4247 | goto __err; | |
4248 | err = snd_config_imake_integer(&v, "integer", card); | |
4249 | if (err < 0) | |
4250 | goto __err; | |
4251 | err = snd_config_add(private_data, v); | |
4252 | if (err < 0) { | |
4253 | snd_config_delete(v); | |
4254 | goto __err; | |
4255 | } | |
4256 | err = snd_config_imake_string(&v, "string", driver); | |
4257 | if (err < 0) | |
4258 | goto __err; | |
4259 | err = snd_config_add(private_data, v); | |
4260 | if (err < 0) { | |
4261 | snd_config_delete(v); | |
4262 | goto __err; | |
4263 | } | |
4264 | return private_data; | |
4265 | ||
4266 | __err: | |
4267 | snd_config_delete(private_data); | |
4268 | return NULL; | |
4269 | } | |
4270 | ||
4271 | static int _snd_config_hook_table(snd_config_t *root, snd_config_t *config, snd_config_t *private_data) | |
4272 | { | |
4273 | snd_config_t *n, *tn; | |
4274 | const char *id; | |
4275 | int err; | |
4276 | ||
4277 | if (snd_config_search(config, "table", &n) < 0) | |
4278 | return 0; | |
4279 | if ((err = snd_config_expand(n, root, NULL, private_data, &n)) < 0) { | |
4280 | SNDERR("Unable to expand table compound"); | |
4281 | return err; | |
4282 | } | |
4283 | if (snd_config_search(n, "id", &tn) < 0 || | |
4284 | snd_config_get_string(tn, &id) < 0) { | |
4285 | SNDERR("Unable to find field table.id"); | |
4286 | snd_config_delete(n); | |
4287 | return -EINVAL; | |
4288 | } | |
4289 | if (snd_config_search(n, "value", &tn) < 0 || | |
4290 | snd_config_get_type(tn) != SND_CONFIG_TYPE_STRING) { | |
4291 | SNDERR("Unable to find field table.value"); | |
4292 | snd_config_delete(n); | |
4293 | return -EINVAL; | |
4294 | } | |
4295 | snd_config_remove(tn); | |
4296 | if ((err = snd_config_set_id(tn, id)) < 0) { | |
4297 | snd_config_delete(tn); | |
4298 | snd_config_delete(n); | |
4299 | return err; | |
4300 | } | |
4301 | snd_config_delete(n); | |
4302 | if ((err = snd_config_add(root, tn)) < 0) { | |
4303 | snd_config_delete(tn); | |
4304 | return err; | |
4305 | } | |
4306 | return 0; | |
4307 | } | |
3975 | 4308 | |
3976 | 4309 | /** |
3977 | 4310 | * \brief Loads and parses the given configurations files for each |
3991 | 4324 | int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config, snd_config_t **dst, snd_config_t *private_data ATTRIBUTE_UNUSED) |
3992 | 4325 | { |
3993 | 4326 | int card = -1, err; |
4327 | snd_config_t *loaded; // trace loaded cards | |
3994 | 4328 | |
4329 | err = snd_config_top(&loaded); | |
4330 | if (err < 0) | |
4331 | return err; | |
3995 | 4332 | do { |
3996 | 4333 | err = snd_card_next(&card); |
3997 | 4334 | if (err < 0) |
3998 | return err; | |
4335 | goto __fin_err; | |
3999 | 4336 | if (card >= 0) { |
4000 | snd_config_t *n, *private_data = NULL; | |
4337 | snd_config_t *n, *m, *private_data = NULL; | |
4001 | 4338 | const char *driver; |
4002 | 4339 | char *fdriver = NULL; |
4340 | bool load; | |
4003 | 4341 | err = snd_determine_driver(card, &fdriver); |
4004 | 4342 | if (err < 0) |
4005 | return err; | |
4343 | goto __fin_err; | |
4006 | 4344 | if (snd_config_search(root, fdriver, &n) >= 0) { |
4007 | if (snd_config_get_string(n, &driver) < 0) | |
4345 | if (snd_config_get_string(n, &driver) < 0) { | |
4346 | if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) { | |
4347 | snd_config_get_id(n, &driver); | |
4348 | goto __std; | |
4349 | } | |
4008 | 4350 | goto __err; |
4009 | assert(driver); | |
4351 | } | |
4010 | 4352 | while (1) { |
4011 | 4353 | char *s = strchr(driver, '.'); |
4012 | 4354 | if (s == NULL) |
4018 | 4360 | } else { |
4019 | 4361 | driver = fdriver; |
4020 | 4362 | } |
4021 | err = snd_config_imake_string(&private_data, "string", driver); | |
4363 | __std: | |
4364 | load = true; | |
4365 | err = snd_config_imake_integer(&m, driver, 1); | |
4022 | 4366 | if (err < 0) |
4023 | 4367 | goto __err; |
4024 | err = snd_config_hook_load(root, config, &n, private_data); | |
4368 | err = snd_config_add(loaded, m); | |
4369 | if (err < 0) { | |
4370 | if (err == -EEXIST) { | |
4371 | snd_config_delete(m); | |
4372 | load = false; | |
4373 | } else { | |
4374 | goto __err; | |
4375 | } | |
4376 | } | |
4377 | private_data = _snd_config_hook_private_data(card, driver); | |
4378 | if (!private_data) { | |
4379 | err = -ENOMEM; | |
4380 | goto __err; | |
4381 | } | |
4382 | err = _snd_config_hook_table(root, config, private_data); | |
4383 | if (err < 0) | |
4384 | goto __err; | |
4385 | if (load) | |
4386 | err = snd_config_hook_load(root, config, &n, private_data); | |
4025 | 4387 | __err: |
4026 | 4388 | if (private_data) |
4027 | 4389 | snd_config_delete(private_data); |
4028 | 4390 | free(fdriver); |
4029 | 4391 | if (err < 0) |
4030 | return err; | |
4392 | goto __fin_err; | |
4031 | 4393 | } |
4032 | 4394 | } while (card >= 0); |
4395 | snd_config_delete(loaded); | |
4033 | 4396 | *dst = NULL; |
4034 | 4397 | return 0; |
4398 | __fin_err: | |
4399 | snd_config_delete(loaded); | |
4400 | return err; | |
4035 | 4401 | } |
4036 | 4402 | #ifndef DOC_HIDDEN |
4037 | 4403 | SND_DLSYM_BUILD_VERSION(snd_config_hook_load_for_all_cards, SND_CONFIG_DLSYM_VERSION_HOOK); |
4743 | 5109 | if (err < 0) |
4744 | 5110 | SNDERR("function %s returned error: %s", func_name, snd_strerror(err)); |
4745 | 5111 | snd_dlclose(h); |
4746 | if (err >= 0 && eval) { | |
4747 | /* substitute merges compound members */ | |
4748 | /* we don't want merging at all */ | |
4749 | err = snd_config_delete_compound_members(src); | |
4750 | if (err >= 0) | |
4751 | err = snd_config_substitute(src, eval); | |
4752 | } | |
5112 | if (err >= 0 && eval) | |
5113 | err = snd_config_substitute(src, eval); | |
4753 | 5114 | } |
4754 | 5115 | _errbuf: |
4755 | 5116 | free(buf); |
5068 | 5429 | const char *new = str; |
5069 | 5430 | const char *tmp; |
5070 | 5431 | char *val = NULL; |
5432 | ||
5433 | sub = NULL; | |
5071 | 5434 | err = parse_arg(&new, &varlen, &val); |
5072 | 5435 | if (err < 0) |
5073 | 5436 | goto _err; |
5092 | 5455 | err = snd_config_search(subs, var, &sub); |
5093 | 5456 | if (err >= 0) |
5094 | 5457 | snd_config_delete(sub); |
5458 | sub = NULL; | |
5095 | 5459 | err = snd_config_search(def, "type", &typ); |
5096 | 5460 | if (err < 0) { |
5097 | 5461 | _invalid_type: |
5157 | 5521 | err = snd_config_add(subs, sub); |
5158 | 5522 | if (err < 0) { |
5159 | 5523 | _err: |
5524 | if (sub) | |
5525 | snd_config_delete(sub); | |
5160 | 5526 | free(val); |
5161 | 5527 | return err; |
5162 | 5528 | } |
77 | 77 | #include <stdio.h> |
78 | 78 | #include <string.h> |
79 | 79 | #include <ctype.h> |
80 | #include <limits.h> | |
80 | 81 | #include "local.h" |
81 | 82 | |
82 | 83 | /** |
139 | 140 | if (err < 0) |
140 | 141 | goto _invalid_value; |
141 | 142 | return err; |
143 | } | |
144 | ||
145 | /** | |
146 | * \brief Gets the card number from a configuration node. | |
147 | * \param conf Handle to the configuration node to be parsed. | |
148 | * \return The card number if successful, otherwise a negative error code. | |
149 | */ | |
150 | int snd_config_get_card(const snd_config_t *conf) | |
151 | { | |
152 | const char *str, *id; | |
153 | long v; | |
154 | int err; | |
155 | ||
156 | if (snd_config_get_integer(conf, &v) < 0) { | |
157 | if (snd_config_get_string(conf, &str)) { | |
158 | if (snd_config_get_id(conf, &id) >= 0) | |
159 | SNDERR("Invalid field %s", id); | |
160 | return -EINVAL; | |
161 | } | |
162 | err = snd_card_get_index(str); | |
163 | if (err < 0) { | |
164 | SNDERR("Cannot get card index for %s", str); | |
165 | return err; | |
166 | } | |
167 | v = err; | |
168 | } | |
169 | if (v < 0 || v > INT_MAX) | |
170 | return -EINVAL; | |
171 | return v; | |
142 | 172 | } |
143 | 173 | |
144 | 174 | /** |
418 | 448 | tmp = realloc(res, len + len1 + 1); |
419 | 449 | if (tmp == NULL) { |
420 | 450 | free(ptr); |
421 | free(res); | |
422 | 451 | err = -ENOMEM; |
423 | 452 | goto __error; |
424 | 453 | } |
439 | 468 | err = snd_config_get_id(src, &id); |
440 | 469 | if (err >= 0) |
441 | 470 | err = snd_config_imake_string(dst, id, res); |
471 | __error: | |
442 | 472 | free(res); |
443 | __error: | |
444 | 473 | return err; |
445 | 474 | } |
446 | 475 | #ifndef DOC_HIDDEN |
615 | 644 | } |
616 | 645 | #endif |
617 | 646 | |
647 | int _snd_func_private_data(snd_config_t **dst, snd_config_t *src, | |
648 | snd_config_t **private_data, const char *id) | |
649 | { | |
650 | int err; | |
651 | ||
652 | if (*private_data == NULL) | |
653 | return snd_config_copy(dst, src); | |
654 | if (snd_config_get_type(*private_data) == SND_CONFIG_TYPE_COMPOUND) { | |
655 | err = snd_config_search(*private_data, id, private_data); | |
656 | if (err) | |
657 | goto notfound; | |
658 | } | |
659 | err = snd_config_test_id(*private_data, id); | |
660 | if (err) { | |
661 | notfound: | |
662 | SNDERR("field %s not found", id); | |
663 | return -EINVAL; | |
664 | } | |
665 | return 0; | |
666 | } | |
667 | ||
668 | ||
618 | 669 | /** |
619 | 670 | * \brief Returns the string from \c private_data. |
620 | 671 | * \param dst The function puts the handle to the result configuration node |
638 | 689 | int err; |
639 | 690 | const char *str, *id; |
640 | 691 | |
641 | if (private_data == NULL) | |
642 | return snd_config_copy(dst, src); | |
643 | err = snd_config_test_id(private_data, "string"); | |
644 | if (err) { | |
645 | SNDERR("field string not found"); | |
646 | return -EINVAL; | |
647 | } | |
692 | err = _snd_func_private_data(dst, src, &private_data, "string"); | |
693 | if (err) | |
694 | return err; | |
648 | 695 | err = snd_config_get_string(private_data, &str); |
649 | 696 | if (err < 0) { |
650 | 697 | SNDERR("field string is not a string"); |
657 | 704 | } |
658 | 705 | #ifndef DOC_HIDDEN |
659 | 706 | SND_DLSYM_BUILD_VERSION(snd_func_private_string, SND_CONFIG_DLSYM_VERSION_EVALUATE); |
707 | #endif | |
708 | ||
709 | /** | |
710 | * \brief Returns the integer from \c private_data. | |
711 | * \param dst The function puts the handle to the result configuration node | |
712 | * (with type integer) at the address specified by \p dst. | |
713 | * \param root Handle to the root source node. | |
714 | * \param src Handle to the source node. | |
715 | * \param private_data Handle to the \c private_data node (type integer, | |
716 | * id "integer"). | |
717 | * \return A non-negative value if successful, otherwise a negative error code. | |
718 | * | |
719 | * Example: | |
720 | \code | |
721 | { | |
722 | @func private_integer | |
723 | } | |
724 | \endcode | |
725 | */ | |
726 | int snd_func_private_integer(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED, | |
727 | snd_config_t *src, snd_config_t *private_data) | |
728 | { | |
729 | int err; | |
730 | const char *id; | |
731 | long val; | |
732 | ||
733 | err = _snd_func_private_data(dst, src, &private_data, "integer"); | |
734 | if (err) | |
735 | return err; | |
736 | err = snd_config_get_integer(private_data, &val); | |
737 | if (err < 0) { | |
738 | SNDERR("field integer is not a string"); | |
739 | return err; | |
740 | } | |
741 | err = snd_config_get_id(src, &id); | |
742 | if (err >= 0) | |
743 | err = snd_config_imake_integer(dst, id, val); | |
744 | return err; | |
745 | } | |
746 | #ifndef DOC_HIDDEN | |
747 | SND_DLSYM_BUILD_VERSION(snd_func_private_integer, SND_CONFIG_DLSYM_VERSION_EVALUATE); | |
660 | 748 | #endif |
661 | 749 | |
662 | 750 | #ifndef DOC_HIDDEN |
0 | 0 | EXTRA_LTLIBRARIES = libcontrol.la |
1 | 1 | |
2 | 2 | libcontrol_la_SOURCES = cards.c tlv.c namehint.c hcontrol.c \ |
3 | control.c control_hw.c setup.c ctlparse.c \ | |
4 | control_symbols.c | |
3 | control.c control_hw.c control_empty.c \ | |
4 | setup.c ctlparse.c \ | |
5 | control_plugin.c control_symbols.c | |
6 | if BUILD_CTL_PLUGIN_REMAP | |
7 | libcontrol_la_SOURCES += control_remap.c | |
8 | endif | |
5 | 9 | if BUILD_CTL_PLUGIN_SHM |
6 | 10 | libcontrol_la_SOURCES += control_shm.c |
7 | 11 | endif |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
87 | 87 | POST_UNINSTALL = : |
88 | 88 | build_triplet = @build@ |
89 | 89 | host_triplet = @host@ |
90 | @BUILD_CTL_PLUGIN_SHM_TRUE@am__append_1 = control_shm.c | |
91 | @BUILD_CTL_PLUGIN_EXT_TRUE@am__append_2 = control_ext.c | |
90 | @BUILD_CTL_PLUGIN_REMAP_TRUE@am__append_1 = control_remap.c | |
91 | @BUILD_CTL_PLUGIN_SHM_TRUE@am__append_2 = control_shm.c | |
92 | @BUILD_CTL_PLUGIN_EXT_TRUE@am__append_3 = control_ext.c | |
92 | 93 | subdir = src/control |
93 | 94 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 |
94 | 95 | am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ |
106 | 107 | CONFIG_CLEAN_VPATH_FILES = |
107 | 108 | libcontrol_la_LIBADD = |
108 | 109 | am__libcontrol_la_SOURCES_DIST = cards.c tlv.c namehint.c hcontrol.c \ |
109 | control.c control_hw.c setup.c ctlparse.c control_symbols.c \ | |
110 | control.c control_hw.c control_empty.c setup.c ctlparse.c \ | |
111 | control_plugin.c control_symbols.c control_remap.c \ | |
110 | 112 | control_shm.c control_ext.c |
111 | @BUILD_CTL_PLUGIN_SHM_TRUE@am__objects_1 = control_shm.lo | |
112 | @BUILD_CTL_PLUGIN_EXT_TRUE@am__objects_2 = control_ext.lo | |
113 | @BUILD_CTL_PLUGIN_REMAP_TRUE@am__objects_1 = control_remap.lo | |
114 | @BUILD_CTL_PLUGIN_SHM_TRUE@am__objects_2 = control_shm.lo | |
115 | @BUILD_CTL_PLUGIN_EXT_TRUE@am__objects_3 = control_ext.lo | |
113 | 116 | am_libcontrol_la_OBJECTS = cards.lo tlv.lo namehint.lo hcontrol.lo \ |
114 | control.lo control_hw.lo setup.lo ctlparse.lo \ | |
115 | control_symbols.lo $(am__objects_1) $(am__objects_2) | |
117 | control.lo control_hw.lo control_empty.lo setup.lo ctlparse.lo \ | |
118 | control_plugin.lo control_symbols.lo $(am__objects_1) \ | |
119 | $(am__objects_2) $(am__objects_3) | |
116 | 120 | libcontrol_la_OBJECTS = $(am_libcontrol_la_OBJECTS) |
117 | 121 | AM_V_lt = $(am__v_lt_@AM_V@) |
118 | 122 | am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) |
134 | 138 | depcomp = $(SHELL) $(top_srcdir)/depcomp |
135 | 139 | am__maybe_remake_depfiles = depfiles |
136 | 140 | am__depfiles_remade = ./$(DEPDIR)/cards.Plo ./$(DEPDIR)/control.Plo \ |
137 | ./$(DEPDIR)/control_ext.Plo ./$(DEPDIR)/control_hw.Plo \ | |
138 | ./$(DEPDIR)/control_shm.Plo ./$(DEPDIR)/control_symbols.Plo \ | |
139 | ./$(DEPDIR)/ctlparse.Plo ./$(DEPDIR)/hcontrol.Plo \ | |
140 | ./$(DEPDIR)/namehint.Plo ./$(DEPDIR)/setup.Plo \ | |
141 | ./$(DEPDIR)/tlv.Plo | |
141 | ./$(DEPDIR)/control_empty.Plo ./$(DEPDIR)/control_ext.Plo \ | |
142 | ./$(DEPDIR)/control_hw.Plo ./$(DEPDIR)/control_plugin.Plo \ | |
143 | ./$(DEPDIR)/control_remap.Plo ./$(DEPDIR)/control_shm.Plo \ | |
144 | ./$(DEPDIR)/control_symbols.Plo ./$(DEPDIR)/ctlparse.Plo \ | |
145 | ./$(DEPDIR)/hcontrol.Plo ./$(DEPDIR)/namehint.Plo \ | |
146 | ./$(DEPDIR)/setup.Plo ./$(DEPDIR)/tlv.Plo | |
142 | 147 | am__mv = mv -f |
143 | 148 | COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ |
144 | 149 | $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
309 | 314 | prefix = @prefix@ |
310 | 315 | program_transform_name = @program_transform_name@ |
311 | 316 | psdir = @psdir@ |
317 | runstatedir = @runstatedir@ | |
312 | 318 | sbindir = @sbindir@ |
313 | 319 | sharedstatedir = @sharedstatedir@ |
314 | 320 | srcdir = @srcdir@ |
319 | 325 | top_srcdir = @top_srcdir@ |
320 | 326 | EXTRA_LTLIBRARIES = libcontrol.la |
321 | 327 | libcontrol_la_SOURCES = cards.c tlv.c namehint.c hcontrol.c control.c \ |
322 | control_hw.c setup.c ctlparse.c control_symbols.c \ | |
323 | $(am__append_1) $(am__append_2) | |
328 | control_hw.c control_empty.c setup.c ctlparse.c \ | |
329 | control_plugin.c control_symbols.c $(am__append_1) \ | |
330 | $(am__append_2) $(am__append_3) | |
324 | 331 | noinst_HEADERS = control_local.h |
325 | 332 | AM_CPPFLAGS = -I$(top_srcdir)/include |
326 | 333 | all: all-am |
368 | 375 | |
369 | 376 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cards.Plo@am__quote@ # am--include-marker |
370 | 377 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Plo@am__quote@ # am--include-marker |
378 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control_empty.Plo@am__quote@ # am--include-marker | |
371 | 379 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control_ext.Plo@am__quote@ # am--include-marker |
372 | 380 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control_hw.Plo@am__quote@ # am--include-marker |
381 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control_plugin.Plo@am__quote@ # am--include-marker | |
382 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control_remap.Plo@am__quote@ # am--include-marker | |
373 | 383 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control_shm.Plo@am__quote@ # am--include-marker |
374 | 384 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control_symbols.Plo@am__quote@ # am--include-marker |
375 | 385 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctlparse.Plo@am__quote@ # am--include-marker |
537 | 547 | distclean: distclean-am |
538 | 548 | -rm -f ./$(DEPDIR)/cards.Plo |
539 | 549 | -rm -f ./$(DEPDIR)/control.Plo |
550 | -rm -f ./$(DEPDIR)/control_empty.Plo | |
540 | 551 | -rm -f ./$(DEPDIR)/control_ext.Plo |
541 | 552 | -rm -f ./$(DEPDIR)/control_hw.Plo |
553 | -rm -f ./$(DEPDIR)/control_plugin.Plo | |
554 | -rm -f ./$(DEPDIR)/control_remap.Plo | |
542 | 555 | -rm -f ./$(DEPDIR)/control_shm.Plo |
543 | 556 | -rm -f ./$(DEPDIR)/control_symbols.Plo |
544 | 557 | -rm -f ./$(DEPDIR)/ctlparse.Plo |
593 | 606 | maintainer-clean: maintainer-clean-am |
594 | 607 | -rm -f ./$(DEPDIR)/cards.Plo |
595 | 608 | -rm -f ./$(DEPDIR)/control.Plo |
609 | -rm -f ./$(DEPDIR)/control_empty.Plo | |
596 | 610 | -rm -f ./$(DEPDIR)/control_ext.Plo |
597 | 611 | -rm -f ./$(DEPDIR)/control_hw.Plo |
612 | -rm -f ./$(DEPDIR)/control_plugin.Plo | |
613 | -rm -f ./$(DEPDIR)/control_remap.Plo | |
598 | 614 | -rm -f ./$(DEPDIR)/control_shm.Plo |
599 | 615 | -rm -f ./$(DEPDIR)/control_symbols.Plo |
600 | 616 | -rm -f ./$(DEPDIR)/ctlparse.Plo |
76 | 76 | - Its name |
77 | 77 | - Its index |
78 | 78 | |
79 | An element can be identified either by its numid or by the tuple | |
80 | (interface type, device, subdevice, name, index). This tuple is always | |
81 | the same (driver updates can change it, but in practice this is | |
82 | rare). The numid can change on each boot. In case of an USB sound | |
83 | card, the numid can also change when it is reconnected. | |
84 | ||
79 | An element can be identified either by its short numid or by the full | |
80 | set of fields (interface type, device, subdevice, name, index). | |
81 | This set of fields is always the same (driver updates can change it, | |
82 | but in practice this is rare). The numid can change on each boot. | |
83 | In case of an USB sound card, the numid can also change when it | |
84 | is reconnected. The short numid is used to reduce the lookup time. | |
85 | 85 | |
86 | 86 | \section element_lists Element Lists |
87 | 87 | |
152 | 152 | #include <signal.h> |
153 | 153 | #include <poll.h> |
154 | 154 | #include <stdbool.h> |
155 | #include <limits.h> | |
155 | 156 | #include "control_local.h" |
156 | 157 | |
157 | 158 | /** |
408 | 409 | #define validate_element_member_dimension(info) true |
409 | 410 | #endif /* deprecated */ |
410 | 411 | |
412 | #define USER_ACCESS_DEFAULT (\ | |
413 | SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | |
414 | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |\ | |
415 | SNDRV_CTL_ELEM_ACCESS_USER) | |
416 | ||
417 | #define USER_ACCESS_SETTABLE (\ | |
418 | SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | |
419 | SNDRV_CTL_ELEM_ACCESS_VOLATILE |\ | |
420 | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |\ | |
421 | SNDRV_CTL_ELEM_ACCESS_INACTIVE |\ | |
422 | SNDRV_CTL_ELEM_ACCESS_USER) | |
423 | ||
424 | static inline int set_user_access(snd_ctl_elem_info_t *info) | |
425 | { | |
426 | if (info->access == 0) { | |
427 | info->access = USER_ACCESS_DEFAULT; | |
428 | } else { | |
429 | if ((info->access & SNDRV_CTL_ELEM_ACCESS_READWRITE) == 0) | |
430 | return -1; | |
431 | if (info->access & ~USER_ACCESS_SETTABLE) | |
432 | return -1; | |
433 | info->access |= SNDRV_CTL_ELEM_ACCESS_USER; | |
434 | } | |
435 | return 0; | |
436 | } | |
437 | ||
438 | int __snd_ctl_add_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info, | |
439 | unsigned int element_count, | |
440 | unsigned int member_count) | |
441 | { | |
442 | if (ctl == NULL || info->id.name[0] == '\0') | |
443 | return -EINVAL; | |
444 | ||
445 | if (set_user_access(info)) | |
446 | return -EINVAL; | |
447 | ||
448 | info->owner = element_count; | |
449 | info->count = member_count; | |
450 | ||
451 | if (!validate_element_member_dimension(info)) | |
452 | return -EINVAL; | |
453 | ||
454 | return ctl->ops->element_add(ctl, info); | |
455 | } | |
456 | ||
411 | 457 | /** |
412 | 458 | * \brief Create and add some user-defined control elements of integer type. |
413 | 459 | * \param ctl A handle of backend module for control interface. |
414 | * \param info Common iformation for a new element set, with ID of the first new | |
460 | * \param info Common information for a new element set, with ID of the first new | |
415 | 461 | * element. |
416 | 462 | * \param element_count The number of elements added by this operation. |
417 | 463 | * \param member_count The number of members which a element has to |
461 | 507 | unsigned int numid; |
462 | 508 | int err; |
463 | 509 | |
464 | if (ctl == NULL || info == NULL || info->id.name[0] == '\0') | |
510 | if (info == NULL) | |
465 | 511 | return -EINVAL; |
466 | 512 | |
467 | 513 | info->type = SND_CTL_ELEM_TYPE_INTEGER; |
468 | info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | |
469 | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | | |
470 | SNDRV_CTL_ELEM_ACCESS_USER; | |
471 | info->owner = element_count; | |
472 | info->count = member_count; | |
473 | 514 | info->value.integer.min = min; |
474 | 515 | info->value.integer.max = max; |
475 | 516 | info->value.integer.step = step; |
476 | 517 | |
477 | if (!validate_element_member_dimension(info)) | |
478 | return -EINVAL; | |
479 | ||
480 | err = ctl->ops->element_add(ctl, info); | |
518 | err = __snd_ctl_add_elem_set(ctl, info, element_count, member_count); | |
481 | 519 | if (err < 0) |
482 | 520 | return err; |
483 | 521 | numid = snd_ctl_elem_id_get_numid(&info->id); |
501 | 539 | /** |
502 | 540 | * \brief Create and add some user-defined control elements of integer64 type. |
503 | 541 | * \param ctl A handle of backend module for control interface. |
504 | * \param info Common iformation for a new element set, with ID of the first new | |
542 | * \param info Common information for a new element set, with ID of the first new | |
505 | 543 | * element. |
506 | 544 | * \param element_count The number of elements added by this operation. |
507 | 545 | * \param member_count The number of members which a element has to |
551 | 589 | unsigned int numid; |
552 | 590 | int err; |
553 | 591 | |
554 | if (ctl == NULL || info == NULL || info->id.name[0] == '\0') | |
592 | if (info == NULL) | |
555 | 593 | return -EINVAL; |
556 | 594 | |
557 | 595 | info->type = SND_CTL_ELEM_TYPE_INTEGER64; |
558 | info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | |
559 | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | | |
560 | SNDRV_CTL_ELEM_ACCESS_USER; | |
561 | info->owner = element_count; | |
562 | info->count = member_count; | |
563 | 596 | info->value.integer64.min = min; |
564 | 597 | info->value.integer64.max = max; |
565 | 598 | info->value.integer64.step = step; |
566 | 599 | |
567 | if (!validate_element_member_dimension(info)) | |
568 | return -EINVAL; | |
569 | ||
570 | err = ctl->ops->element_add(ctl, info); | |
600 | err = __snd_ctl_add_elem_set(ctl, info, element_count, member_count); | |
571 | 601 | if (err < 0) |
572 | 602 | return err; |
573 | 603 | numid = snd_ctl_elem_id_get_numid(&info->id); |
591 | 621 | /** |
592 | 622 | * \brief Create and add some user-defined control elements of boolean type. |
593 | 623 | * \param ctl A handle of backend module for control interface. |
594 | * \param info Common iformation for a new element set, with ID of the first new | |
624 | * \param info Common information for a new element set, with ID of the first new | |
595 | 625 | * element. |
596 | 626 | * \param element_count The number of elements added by this operation. |
597 | 627 | * \param member_count The number of members which a element has to |
630 | 660 | unsigned int element_count, |
631 | 661 | unsigned int member_count) |
632 | 662 | { |
633 | if (ctl == NULL || info == NULL || info->id.name[0] == '\0') | |
663 | if (info == NULL) | |
634 | 664 | return -EINVAL; |
635 | 665 | |
636 | 666 | info->type = SND_CTL_ELEM_TYPE_BOOLEAN; |
637 | info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | |
638 | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | | |
639 | SNDRV_CTL_ELEM_ACCESS_USER; | |
640 | info->owner = element_count; | |
641 | info->count = member_count; | |
642 | 667 | info->value.integer.min = 0; |
643 | 668 | info->value.integer.max = 1; |
644 | 669 | |
645 | if (!validate_element_member_dimension(info)) | |
646 | return -EINVAL; | |
647 | ||
648 | return ctl->ops->element_add(ctl, info); | |
670 | return __snd_ctl_add_elem_set(ctl, info, element_count, member_count); | |
649 | 671 | } |
650 | 672 | |
651 | 673 | /** |
652 | 674 | * \brief Create and add some user-defined control elements of enumerated type. |
653 | 675 | * \param ctl A handle of backend module for control interface. |
654 | * \param info Common iformation for a new element set, with ID of the first new | |
676 | * \param info Common information for a new element set, with ID of the first new | |
655 | 677 | * element. |
656 | 678 | * \param element_count The number of elements added by this operation. |
657 | 679 | * \param member_count The number of members which a element has to |
701 | 723 | char *buf, *p; |
702 | 724 | int err; |
703 | 725 | |
704 | if (ctl == NULL || info == NULL || info->id.name[0] == '\0' || | |
705 | labels == NULL) | |
726 | if (info == NULL || labels == NULL) | |
706 | 727 | return -EINVAL; |
707 | 728 | |
708 | 729 | info->type = SND_CTL_ELEM_TYPE_ENUMERATED; |
709 | info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | |
710 | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | | |
711 | SNDRV_CTL_ELEM_ACCESS_USER; | |
712 | 730 | info->owner = element_count; |
713 | 731 | info->count = member_count; |
714 | 732 | info->value.enumerated.items = items; |
729 | 747 | p += strlen(labels[i]) + 1; |
730 | 748 | } |
731 | 749 | |
732 | if (!validate_element_member_dimension(info)) | |
733 | return -EINVAL; | |
734 | ||
735 | err = ctl->ops->element_add(ctl, info); | |
750 | err = __snd_ctl_add_elem_set(ctl, info, element_count, member_count); | |
736 | 751 | |
737 | 752 | free(buf); |
738 | 753 | |
742 | 757 | /** |
743 | 758 | * \brief Create and add some user-defined control elements of bytes type. |
744 | 759 | * \param ctl A handle of backend module for control interface. |
745 | * \param info Common iformation for a new element set, with ID of the first new | |
760 | * \param info Common information for a new element set, with ID of the first new | |
746 | 761 | * element. |
747 | 762 | * \param element_count The number of elements added by this operation. |
748 | 763 | * \param member_count The number of members which a element has to |
782 | 797 | unsigned int element_count, |
783 | 798 | unsigned int member_count) |
784 | 799 | { |
785 | if (ctl == NULL || info == NULL || info->id.name[0] == '\0') | |
800 | if (info == NULL) | |
786 | 801 | return -EINVAL; |
787 | 802 | |
788 | 803 | info->type = SND_CTL_ELEM_TYPE_BYTES; |
789 | info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | |
790 | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | | |
791 | SNDRV_CTL_ELEM_ACCESS_USER; | |
792 | info->owner = element_count; | |
793 | info->count = member_count; | |
794 | ||
795 | if (!validate_element_member_dimension(info)) | |
796 | return -EINVAL; | |
797 | ||
798 | return ctl->ops->element_add(ctl, info); | |
804 | ||
805 | return __snd_ctl_add_elem_set(ctl, info, element_count, member_count); | |
799 | 806 | } |
800 | 807 | |
801 | 808 | /** |
1337 | 1344 | } |
1338 | 1345 | |
1339 | 1346 | static const char *const build_in_ctls[] = { |
1340 | "hw", "shm", NULL | |
1347 | "hw", "empty", "remap", "shm", NULL | |
1341 | 1348 | }; |
1342 | 1349 | |
1343 | 1350 | static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name, |
1461 | 1468 | return err; |
1462 | 1469 | } |
1463 | 1470 | |
1464 | static int snd_ctl_open_noupdate(snd_ctl_t **ctlp, snd_config_t *root, const char *name, int mode) | |
1471 | static int snd_ctl_open_noupdate(snd_ctl_t **ctlp, snd_config_t *root, | |
1472 | const char *name, int mode, int hop) | |
1465 | 1473 | { |
1466 | 1474 | int err; |
1467 | 1475 | snd_config_t *ctl_conf; |
1476 | const char *str; | |
1477 | ||
1468 | 1478 | err = snd_config_search_definition(root, "ctl", name, &ctl_conf); |
1469 | 1479 | if (err < 0) { |
1470 | 1480 | SNDERR("Invalid CTL %s", name); |
1471 | 1481 | return err; |
1472 | 1482 | } |
1473 | err = snd_ctl_open_conf(ctlp, name, root, ctl_conf, mode); | |
1483 | if (snd_config_get_string(ctl_conf, &str) >= 0) | |
1484 | err = snd_ctl_open_noupdate(ctlp, root, str, mode, hop + 1); | |
1485 | else { | |
1486 | snd_config_set_hop(ctl_conf, hop); | |
1487 | err = snd_ctl_open_conf(ctlp, name, root, ctl_conf, mode); | |
1488 | } | |
1474 | 1489 | snd_config_delete(ctl_conf); |
1475 | 1490 | return err; |
1476 | 1491 | } |
1492 | ||
1493 | #ifndef DOC_HIDDEN | |
1494 | int _snd_ctl_open_named_child(snd_ctl_t **pctl, const char *name, | |
1495 | snd_config_t *root, snd_config_t *conf, | |
1496 | int mode, snd_config_t *parent_conf) | |
1497 | { | |
1498 | const char *str; | |
1499 | int hop; | |
1500 | ||
1501 | if ((hop = snd_config_check_hop(parent_conf)) < 0) | |
1502 | return hop; | |
1503 | if (snd_config_get_string(conf, &str) >= 0) | |
1504 | return snd_ctl_open_noupdate(pctl, root, str, mode, hop + 1); | |
1505 | return snd_ctl_open_conf(pctl, name, root, conf, mode); | |
1506 | } | |
1507 | #endif | |
1477 | 1508 | |
1478 | 1509 | /** |
1479 | 1510 | * \brief Opens a CTL |
1488 | 1519 | int err; |
1489 | 1520 | |
1490 | 1521 | assert(ctlp && name); |
1491 | err = snd_config_update_ref(&top); | |
1492 | if (err < 0) | |
1493 | return err; | |
1494 | err = snd_ctl_open_noupdate(ctlp, top, name, mode); | |
1522 | if (_snd_is_ucm_device(name)) { | |
1523 | name = uc_mgr_alibcfg_by_device(&top, name); | |
1524 | if (name == NULL) | |
1525 | return -ENODEV; | |
1526 | } else { | |
1527 | err = snd_config_update_ref(&top); | |
1528 | if (err < 0) | |
1529 | return err; | |
1530 | } | |
1531 | err = snd_ctl_open_noupdate(ctlp, top, name, mode, 0); | |
1495 | 1532 | snd_config_unref(top); |
1496 | 1533 | return err; |
1497 | 1534 | } |
1508 | 1545 | int mode, snd_config_t *lconf) |
1509 | 1546 | { |
1510 | 1547 | assert(ctlp && name && lconf); |
1511 | return snd_ctl_open_noupdate(ctlp, lconf, name, mode); | |
1548 | return snd_ctl_open_noupdate(ctlp, lconf, name, mode, 0); | |
1512 | 1549 | } |
1513 | 1550 | |
1514 | 1551 | /** |
1525 | 1562 | { |
1526 | 1563 | int err; |
1527 | 1564 | assert(ctlp && name && root); |
1528 | err = snd_ctl_open_noupdate(ctlp, root, name, mode); | |
1565 | err = snd_ctl_open_noupdate(ctlp, root, name, mode, 0); | |
1529 | 1566 | if (err >= 0) { |
1530 | 1567 | free((*ctlp)->name); |
1531 | 1568 | (*ctlp)->name = orig_name ? strdup(orig_name) : NULL; |
1792 | 1829 | } |
1793 | 1830 | |
1794 | 1831 | /** |
1832 | * \brief compare one #snd_ctl_elem_id_t to another using numid | |
1833 | * \param id1 pointer to first id | |
1834 | * \param id2 pointer to second id | |
1835 | * \retval zero when values are identical, other value on a difference (like strcmp) | |
1836 | * | |
1837 | * This comparison ignores the set of fields part. | |
1838 | * | |
1839 | * The return value can be used for sorting like qsort(). It gives persistent | |
1840 | * results. | |
1841 | */ | |
1842 | int snd_ctl_elem_id_compare_numid(const snd_ctl_elem_id_t *id1, const snd_ctl_elem_id_t *id2) | |
1843 | { | |
1844 | int64_t d; | |
1845 | ||
1846 | assert(id1 && id2); | |
1847 | d = (int64_t)id1->numid - (int64_t)id2->numid; | |
1848 | if (d & ((int64_t)INT_MAX + 1)) { /* fast path */ | |
1849 | if (d > INT_MAX) | |
1850 | d = INT_MAX; | |
1851 | else if (d < INT_MIN) | |
1852 | d = INT_MIN; | |
1853 | } | |
1854 | return d; | |
1855 | } | |
1856 | ||
1857 | /** | |
1858 | * \brief compare one #snd_ctl_elem_id_t to another | |
1859 | * \param id1 pointer to first id | |
1860 | * \param id2 pointer to second id | |
1861 | * \retval zero when values are identical, other value on a difference (like strcmp) | |
1862 | * | |
1863 | * This comparison ignores the numid part. The numid comparison can be easily | |
1864 | * implemented using snd_ctl_elem_id_get_numid() calls. | |
1865 | * | |
1866 | * The identifier set fields are compared in this order: interface, device, | |
1867 | * subdevice, name, index. | |
1868 | * | |
1869 | * The return value can be used for sorting like qsort(). It gives persistent | |
1870 | * results. | |
1871 | */ | |
1872 | int snd_ctl_elem_id_compare_set(const snd_ctl_elem_id_t *id1, const snd_ctl_elem_id_t *id2) | |
1873 | { | |
1874 | int d; | |
1875 | ||
1876 | assert(id1 && id2); | |
1877 | /* although those values are unsigned integer, practically, */ | |
1878 | /* the useable limit is really much lower */ | |
1879 | assert((id1->iface | id1->device | id1->subdevice | id1->index) <= INT_MAX); | |
1880 | assert((id2->iface | id2->device | id2->subdevice | id1->index) <= INT_MAX); | |
1881 | d = id1->iface - id2->iface; | |
1882 | if (d != 0) | |
1883 | return d; | |
1884 | d = id1->device - id2->device; | |
1885 | if (d != 0) | |
1886 | return d; | |
1887 | d = id1->subdevice - id2->subdevice; | |
1888 | if (d != 0) | |
1889 | return d; | |
1890 | d = strcmp((const char *)id1->name, (const char *)id2->name); | |
1891 | if (d != 0) | |
1892 | return d; | |
1893 | return id1->index - id2->index; | |
1894 | } | |
1895 | ||
1896 | /** | |
1795 | 1897 | * \brief Get numeric identifier from a CTL element identifier |
1796 | 1898 | * \param obj CTL element identifier |
1797 | 1899 | * \return CTL element numeric identifier |
2890 | 2992 | } |
2891 | 2993 | |
2892 | 2994 | /** |
2995 | * \brief Set readability/writeability parameter of a CTL element id/info | |
2996 | * \param obj CTL element id/info | |
2997 | * \param rval readability part of element identifier | |
2998 | * \param wval writeability part of element identifier | |
2999 | */ | |
3000 | void snd_ctl_elem_info_set_read_write(snd_ctl_elem_info_t *obj, int rval, int wval) | |
3001 | { | |
3002 | assert(obj); | |
3003 | obj->access = (obj->access & ~SNDRV_CTL_ELEM_ACCESS_READWRITE) | | |
3004 | (rval ? SNDRV_CTL_ELEM_ACCESS_READ : 0) | | |
3005 | (wval ? SNDRV_CTL_ELEM_ACCESS_WRITE : 0); | |
3006 | } | |
3007 | ||
3008 | /** | |
3009 | * \brief Set TLV readability/writeability parameter of a CTL element id/info | |
3010 | * \param obj CTL element id/info | |
3011 | * \param rval TLV readability part of element identifier | |
3012 | * \param wval TLV writeability part of element identifier | |
3013 | */ | |
3014 | void snd_ctl_elem_info_set_tlv_read_write(snd_ctl_elem_info_t *obj, int rval, int wval) | |
3015 | { | |
3016 | assert(obj); | |
3017 | obj->access = (obj->access & ~SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) | | |
3018 | (rval ? SNDRV_CTL_ELEM_ACCESS_TLV_READ : 0) | | |
3019 | (wval ? SNDRV_CTL_ELEM_ACCESS_TLV_WRITE : 0); | |
3020 | } | |
3021 | ||
3022 | /** | |
3023 | * \brief Set inactive parameter of a CTL element id/info | |
3024 | * \param obj CTL element id/info | |
3025 | * \param val inactive part of element identifier | |
3026 | */ | |
3027 | void snd_ctl_elem_info_set_inactive(snd_ctl_elem_info_t *obj, int val) | |
3028 | { | |
3029 | assert(obj); | |
3030 | obj->access = (obj->access & ~SNDRV_CTL_ELEM_ACCESS_INACTIVE) | | |
3031 | (val ? SNDRV_CTL_ELEM_ACCESS_INACTIVE : 0); | |
3032 | } | |
3033 | ||
3034 | /** | |
2893 | 3035 | * \brief Get size of data structure for an element. |
2894 | 3036 | * \return Size in bytes. |
2895 | 3037 | */ |
3419 | 3561 | assert(obj && ptr); |
3420 | 3562 | memcpy(&obj->value.iec958, ptr, sizeof(obj->value.iec958)); |
3421 | 3563 | } |
3422 |
0 | /** | |
1 | * \file control/control_empty.c | |
2 | * \ingroup Control_Plugins | |
3 | * \brief Control Empty Plugin Interface | |
4 | * \author Jaroslav Kysela <perex@perex.cz> | |
5 | * \date 2021 | |
6 | */ | |
7 | /* | |
8 | * Control - Empty plugin | |
9 | * Copyright (c) 2021 by Jaroslav Kysela <perex@perex.cz> | |
10 | * | |
11 | * | |
12 | * This library is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU Lesser General Public License as | |
14 | * published by the Free Software Foundation; either version 2.1 of | |
15 | * the License, or (at your option) any later version. | |
16 | * | |
17 | * This program is distributed in the hope that it will be useful, | |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU Lesser General Public License for more details. | |
21 | * | |
22 | * You should have received a copy of the GNU Lesser General Public | |
23 | * License along with this library; if not, write to the Free Software | |
24 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
25 | * | |
26 | */ | |
27 | ||
28 | #include "control_local.h" | |
29 | ||
30 | #ifndef PIC | |
31 | /* entry for static linking */ | |
32 | const char *_snd_module_ctl_empty = ""; | |
33 | #endif | |
34 | ||
35 | /*! \page control_plugins | |
36 | ||
37 | \section control_plugins_empty Plugin: Empty | |
38 | ||
39 | This plugin just redirects the control device to another plugin. | |
40 | ||
41 | \code | |
42 | ctl.name { | |
43 | type empty # Empty Control | |
44 | child STR # Slave name | |
45 | # or | |
46 | child { # Child definition | |
47 | ... | |
48 | } | |
49 | } | |
50 | \endcode | |
51 | ||
52 | \subsection control_plugins_empty_funcref Function reference | |
53 | ||
54 | <UL> | |
55 | <LI>_snd_ctl_empty_open() | |
56 | </UL> | |
57 | ||
58 | */ | |
59 | ||
60 | /** | |
61 | * \brief Creates a new Empty Control | |
62 | * \param handlep Returns created Control handle | |
63 | * \param name Name of Control | |
64 | * \param root Root configuration node | |
65 | * \param conf Configuration node with empty Control description | |
66 | * \param mode Control mode | |
67 | * \retval zero on success otherwise a negative error code | |
68 | * \warning Using of this function might be dangerous in the sense | |
69 | * of compatibility reasons. The prototype might be freely | |
70 | * changed in future. | |
71 | */ | |
72 | int _snd_ctl_empty_open(snd_ctl_t **handlep, const char *name ATTRIBUTE_UNUSED, | |
73 | snd_config_t *root, snd_config_t *conf, int mode) | |
74 | { | |
75 | snd_config_t *child = NULL; | |
76 | snd_config_iterator_t i, next; | |
77 | ||
78 | snd_config_for_each(i, next, conf) { | |
79 | snd_config_t *n = snd_config_iterator_entry(i); | |
80 | const char *id; | |
81 | if (snd_config_get_id(n, &id) < 0) | |
82 | continue; | |
83 | if (_snd_conf_generic_id(id)) | |
84 | continue; | |
85 | if (strcmp(id, "child") == 0) { | |
86 | child = n; | |
87 | continue; | |
88 | } | |
89 | SNDERR("Unknown field %s", id); | |
90 | return -EINVAL; | |
91 | } | |
92 | if (!child) { | |
93 | SNDERR("child is not defined"); | |
94 | return -EINVAL; | |
95 | } | |
96 | return _snd_ctl_open_named_child(handlep, name, root, child, mode, conf); | |
97 | } | |
98 | #ifndef DOC_HIDDEN | |
99 | SND_DLSYM_BUILD_VERSION(_snd_ctl_empty_open, SND_CONTROL_DLSYM_VERSION); | |
100 | #endif |
0 | /** | |
1 | * \file control/control_hw.c | |
2 | * \brief CTL HW Plugin Interface | |
3 | * \author Jaroslav Kysela <perex@perex.cz> | |
4 | * \date 2000 | |
5 | */ | |
0 | 6 | /* |
1 | 7 | * Control Interface - Hardware |
2 | 8 | * Copyright (c) 1998,1999,2000 by Jaroslav Kysela <perex@perex.cz> |
374 | 380 | .read = snd_ctl_hw_read, |
375 | 381 | }; |
376 | 382 | |
383 | /** | |
384 | * \brief Creates a new hw control | |
385 | * \param handle Returns created control handle | |
386 | * \param name Name of control device | |
387 | * \param card Number of card | |
388 | * \param mode Control mode | |
389 | * \retval zero on success otherwise a negative error code | |
390 | * \warning Using of this function might be dangerous in the sense | |
391 | * of compatibility reasons. The prototype might be freely | |
392 | * changed in future. | |
393 | */ | |
377 | 394 | int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode) |
378 | 395 | { |
379 | 396 | int fd, ver; |
436 | 453 | return 0; |
437 | 454 | } |
438 | 455 | |
456 | /*! \page control_plugins | |
457 | ||
458 | \section control_plugins_hw Plugin: hw | |
459 | ||
460 | This plugin communicates directly with the ALSA kernel driver. It is a raw | |
461 | communication without any conversions. | |
462 | ||
463 | \code | |
464 | control.name { | |
465 | type hw # Kernel PCM | |
466 | card INT/STR # Card name (string) or number (integer) | |
467 | } | |
468 | \endcode | |
469 | ||
470 | \subsection control_plugins_hw_funcref Function reference | |
471 | ||
472 | <UL> | |
473 | <LI>snd_ctl_hw_open() | |
474 | <LI>_snd_ctl_hw_open() | |
475 | </UL> | |
476 | ||
477 | */ | |
478 | ||
479 | /** | |
480 | * \brief Creates a new hw control handle | |
481 | * \param handlep Returns created control handle | |
482 | * \param name Name of control device | |
483 | * \param root Root configuration node | |
484 | * \param conf Configuration node with hw PCM description | |
485 | * \param mode Control Mode | |
486 | * \warning Using of this function might be dangerous in the sense | |
487 | * of compatibility reasons. The prototype might be freely | |
488 | * changed in future. | |
489 | */ | |
439 | 490 | int _snd_ctl_hw_open(snd_ctl_t **handlep, char *name, snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf, int mode) |
440 | 491 | { |
441 | 492 | snd_config_iterator_t i, next; |
442 | 493 | long card = -1; |
443 | const char *str; | |
444 | 494 | int err; |
445 | 495 | snd_config_for_each(i, next, conf) { |
446 | 496 | snd_config_t *n = snd_config_iterator_entry(i); |
450 | 500 | if (_snd_conf_generic_id(id)) |
451 | 501 | continue; |
452 | 502 | if (strcmp(id, "card") == 0) { |
453 | err = snd_config_get_integer(n, &card); | |
454 | if (err < 0) { | |
455 | err = snd_config_get_string(n, &str); | |
456 | if (err < 0) | |
457 | return -EINVAL; | |
458 | card = snd_card_get_index(str); | |
459 | if (card < 0) | |
460 | return card; | |
461 | } | |
503 | err = snd_config_get_card(n); | |
504 | if (err < 0) | |
505 | return err; | |
506 | card = err; | |
462 | 507 | continue; |
463 | 508 | } |
464 | 509 | return -EINVAL; |
467 | 512 | return -EINVAL; |
468 | 513 | return snd_ctl_hw_open(handlep, name, card, mode); |
469 | 514 | } |
515 | #ifndef DOC_HIDDEN | |
470 | 516 | SND_DLSYM_BUILD_VERSION(_snd_ctl_hw_open, SND_CONTROL_DLSYM_VERSION); |
517 | #endif |
105 | 105 | int INTERNAL(snd_ctl_elem_info_get_dimensions)(const snd_ctl_elem_info_t *obj); |
106 | 106 | int INTERNAL(snd_ctl_elem_info_get_dimension)(const snd_ctl_elem_info_t *obj, unsigned int idx); |
107 | 107 | #endif /* INTERNAL */ |
108 | ||
109 | int _snd_ctl_open_named_child(snd_ctl_t **pctl, const char *name, | |
110 | snd_config_t *root, snd_config_t *conf, | |
111 | int mode, snd_config_t *parent_conf); | |
112 | static inline int | |
113 | _snd_ctl_open_child(snd_ctl_t **pctl, snd_config_t *root, | |
114 | snd_config_t *conf, int mode, snd_config_t *parent_conf) | |
115 | { | |
116 | return _snd_ctl_open_named_child(pctl, NULL, root, conf, mode, parent_conf); | |
117 | } | |
118 | ||
119 | int __snd_ctl_add_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info, | |
120 | unsigned int element_count, | |
121 | unsigned int member_count); | |
122 | ||
123 | int __snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, | |
124 | const char *str, | |
125 | const char **ret_ptr); |
0 | /** | |
1 | * \file control/control_plugin.c | |
2 | * \ingroup Control | |
3 | * \brief Control Interface | |
4 | * \author Jaroslav Kysela <perex@perex.cz> | |
5 | * \date 2021 | |
6 | */ | |
7 | /* | |
8 | * Control - Common plugin code | |
9 | * Copyright (c) 2021 by Jaroslav Kysela <perex@perex.cz> | |
10 | * | |
11 | * | |
12 | * This library is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU Lesser General Public License as | |
14 | * published by the Free Software Foundation; either version 2.1 of | |
15 | * the License, or (at your option) any later version. | |
16 | * | |
17 | * This program is distributed in the hope that it will be useful, | |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU Lesser General Public License for more details. | |
21 | * | |
22 | * You should have received a copy of the GNU Lesser General Public | |
23 | * License along with this library; if not, write to the Free Software | |
24 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
25 | * | |
26 | */ | |
27 | ||
28 | /*! | |
29 | ||
30 | \page control_plugins Primitive control plugins | |
31 | ||
32 | Control plugins extends functionality and features of control devices. | |
33 | The plugins take care about various control mapping or so. | |
34 | ||
35 | The child configuration (in one compound): | |
36 | ||
37 | \code | |
38 | ctl.test { | |
39 | type remap | |
40 | child "hw:0" | |
41 | ... map/remap configuration ... | |
42 | } | |
43 | \endcode | |
44 | ||
45 | The child may be defined as compound containing the full specification: | |
46 | ||
47 | \code | |
48 | ctl.test { | |
49 | type remap | |
50 | child { | |
51 | type hw | |
52 | card 0 | |
53 | } | |
54 | ... map/remap configuration ... | |
55 | } | |
56 | \endcode | |
57 | ||
58 | */ | |
59 | ||
60 | #include "control_local.h" | |
61 | #include "control_plugin.h" | |
62 | ||
63 | /* move the common plugin code from control_remap.c here on demand */ |
0 | /** | |
1 | * \file control/control_remap.c | |
2 | * \brief CTL Remap Plugin Interface | |
3 | * \author Jaroslav Kysela <perex@perex.cz> | |
4 | * \date 2021 | |
5 | */ | |
6 | /* | |
7 | * Control - Remap Controls | |
8 | * Copyright (c) 2021 by Jaroslav Kysela <perex@perex.cz> | |
9 | * | |
10 | * | |
11 | * This library is free software; you can redistribute it and/or modify | |
12 | * it under the terms of the GNU Lesser General Public License as | |
13 | * published by the Free Software Foundation; either version 2.1 of | |
14 | * the License, or (at your option) any later version. | |
15 | * | |
16 | * This program is distributed in the hope that it will be useful, | |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | * GNU Lesser General Public License for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU Lesser General Public | |
22 | * License along with this library; if not, write to the Free Software | |
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
24 | * | |
25 | */ | |
26 | ||
27 | #include <stdio.h> | |
28 | #include <stdlib.h> | |
29 | #include <stdint.h> | |
30 | #include <stdarg.h> | |
31 | #include <unistd.h> | |
32 | #include <string.h> | |
33 | #include "control_local.h" | |
34 | ||
35 | #if 0 | |
36 | #define REMAP_DEBUG 1 | |
37 | #define debug(format, args...) fprintf(stderr, format, ##args) | |
38 | #define debug_id(id, format, args...) do { \ | |
39 | char *s = snd_ctl_ascii_elem_id_get(id); \ | |
40 | fprintf(stderr, "%s: ", s); free(s); \ | |
41 | fprintf(stderr, format, ##args); \ | |
42 | } while (0) | |
43 | #else | |
44 | #define REMAP_DEBUG 0 | |
45 | #define debug(format, args...) do { } while (0) | |
46 | #define debug_id(id, format, args...) do { } while (0) | |
47 | #endif | |
48 | ||
49 | #define EREMAPNOTFOUND (888899) | |
50 | ||
51 | #ifndef PIC | |
52 | /* entry for static linking */ | |
53 | const char *_snd_module_control_remap = ""; | |
54 | #endif | |
55 | ||
56 | #ifndef DOC_HIDDEN | |
57 | typedef struct { | |
58 | unsigned int numid_child; | |
59 | unsigned int numid_app; | |
60 | } snd_ctl_numid_t; | |
61 | ||
62 | typedef struct { | |
63 | snd_ctl_elem_id_t id_child; | |
64 | snd_ctl_elem_id_t id_app; | |
65 | } snd_ctl_remap_id_t; | |
66 | ||
67 | typedef struct { | |
68 | snd_ctl_elem_id_t map_id; | |
69 | snd_ctl_elem_type_t type; | |
70 | size_t controls_items; | |
71 | size_t controls_alloc; | |
72 | struct snd_ctl_map_ctl { | |
73 | snd_ctl_elem_id_t id_child; | |
74 | size_t channel_map_items; | |
75 | size_t channel_map_alloc; | |
76 | long *channel_map; | |
77 | } *controls; | |
78 | unsigned int event_mask; | |
79 | } snd_ctl_map_t; | |
80 | ||
81 | typedef struct { | |
82 | snd_ctl_t *child; | |
83 | int numid_remap_active; | |
84 | unsigned int numid_app_last; | |
85 | size_t numid_items; | |
86 | size_t numid_alloc; | |
87 | snd_ctl_numid_t *numid; | |
88 | snd_ctl_numid_t numid_temp; | |
89 | size_t remap_items; | |
90 | size_t remap_alloc; | |
91 | snd_ctl_remap_id_t *remap; | |
92 | size_t map_items; | |
93 | size_t map_alloc; | |
94 | snd_ctl_map_t *map; | |
95 | size_t map_read_queue_head; | |
96 | size_t map_read_queue_tail; | |
97 | snd_ctl_map_t **map_read_queue; | |
98 | } snd_ctl_remap_t; | |
99 | #endif | |
100 | ||
101 | static snd_ctl_numid_t *remap_numid_temp(snd_ctl_remap_t *priv, unsigned int numid) | |
102 | { | |
103 | priv->numid_temp.numid_child = numid; | |
104 | priv->numid_temp.numid_app = numid; | |
105 | return &priv->numid_temp; | |
106 | } | |
107 | ||
108 | static snd_ctl_numid_t *remap_find_numid_app(snd_ctl_remap_t *priv, unsigned int numid_app) | |
109 | { | |
110 | snd_ctl_numid_t *numid; | |
111 | size_t count; | |
112 | ||
113 | if (!priv->numid_remap_active) | |
114 | return remap_numid_temp(priv, numid_app); | |
115 | numid = priv->numid; | |
116 | for (count = priv->numid_items; count > 0; count--, numid++) | |
117 | if (numid_app == numid->numid_app) | |
118 | return numid; | |
119 | return NULL; | |
120 | } | |
121 | ||
122 | static snd_ctl_numid_t *remap_numid_new(snd_ctl_remap_t *priv, unsigned int numid_child, | |
123 | unsigned int numid_app) | |
124 | { | |
125 | snd_ctl_numid_t *numid; | |
126 | ||
127 | if (priv->numid_alloc == priv->numid_items) { | |
128 | numid = realloc(priv->numid, (priv->numid_alloc + 16) * sizeof(*numid)); | |
129 | if (numid == NULL) | |
130 | return NULL; | |
131 | memset(numid + priv->numid_alloc, 0, sizeof(*numid) * 16); | |
132 | priv->numid_alloc += 16; | |
133 | priv->numid = numid; | |
134 | } | |
135 | numid = &priv->numid[priv->numid_items++]; | |
136 | numid->numid_child = numid_child; | |
137 | numid->numid_app = numid_app; | |
138 | debug("new numid: child %u app %u\n", numid->numid_child, numid->numid_app); | |
139 | return numid; | |
140 | } | |
141 | ||
142 | static snd_ctl_numid_t *remap_numid_child_new(snd_ctl_remap_t *priv, unsigned int numid_child) | |
143 | { | |
144 | unsigned int numid_app; | |
145 | ||
146 | if (numid_child == 0) | |
147 | return NULL; | |
148 | if (remap_find_numid_app(priv, numid_child)) { | |
149 | while (remap_find_numid_app(priv, priv->numid_app_last)) | |
150 | priv->numid_app_last++; | |
151 | numid_app = priv->numid_app_last; | |
152 | } else { | |
153 | numid_app = numid_child; | |
154 | } | |
155 | return remap_numid_new(priv, numid_child, numid_app); | |
156 | } | |
157 | ||
158 | static snd_ctl_numid_t *remap_find_numid_child(snd_ctl_remap_t *priv, unsigned int numid_child) | |
159 | { | |
160 | snd_ctl_numid_t *numid; | |
161 | size_t count; | |
162 | ||
163 | if (!priv->numid_remap_active) | |
164 | return remap_numid_temp(priv, numid_child); | |
165 | numid = priv->numid; | |
166 | for (count = priv->numid_items; count > 0; count--, numid++) | |
167 | if (numid_child == numid->numid_child) | |
168 | return numid; | |
169 | return remap_numid_child_new(priv, numid_child); | |
170 | } | |
171 | ||
172 | static snd_ctl_remap_id_t *remap_find_id_child(snd_ctl_remap_t *priv, snd_ctl_elem_id_t *id) | |
173 | { | |
174 | size_t count; | |
175 | snd_ctl_remap_id_t *rid; | |
176 | ||
177 | if (id->numid > 0) { | |
178 | rid = priv->remap; | |
179 | for (count = priv->remap_items; count > 0; count--, rid++) | |
180 | if (id->numid == rid->id_child.numid) | |
181 | return rid; | |
182 | } | |
183 | rid = priv->remap; | |
184 | for (count = priv->remap_items; count > 0; count--, rid++) | |
185 | if (snd_ctl_elem_id_compare_set(id, &rid->id_child) == 0) | |
186 | return rid; | |
187 | return NULL; | |
188 | } | |
189 | ||
190 | static snd_ctl_remap_id_t *remap_find_id_app(snd_ctl_remap_t *priv, snd_ctl_elem_id_t *id) | |
191 | { | |
192 | size_t count; | |
193 | snd_ctl_remap_id_t *rid; | |
194 | ||
195 | if (id->numid > 0) { | |
196 | rid = priv->remap; | |
197 | for (count = priv->remap_items; count > 0; count--, rid++) | |
198 | if (id->numid == rid->id_app.numid) | |
199 | return rid; | |
200 | } | |
201 | rid = priv->remap; | |
202 | for (count = priv->remap_items; count > 0; count--, rid++) | |
203 | if (snd_ctl_elem_id_compare_set(id, &rid->id_app) == 0) | |
204 | return rid; | |
205 | return NULL; | |
206 | } | |
207 | ||
208 | static snd_ctl_map_t *remap_find_map_numid(snd_ctl_remap_t *priv, unsigned int numid) | |
209 | { | |
210 | size_t count; | |
211 | snd_ctl_map_t *map; | |
212 | ||
213 | if (numid == 0) | |
214 | return NULL; | |
215 | map = priv->map; | |
216 | for (count = priv->map_items; count > 0; count--, map++) { | |
217 | if (numid == map->map_id.numid) | |
218 | return map; | |
219 | } | |
220 | return NULL; | |
221 | } | |
222 | static snd_ctl_map_t *remap_find_map_id(snd_ctl_remap_t *priv, snd_ctl_elem_id_t *id) | |
223 | { | |
224 | size_t count; | |
225 | snd_ctl_map_t *map; | |
226 | ||
227 | if (id->numid > 0) | |
228 | return remap_find_map_numid(priv, id->numid); | |
229 | map = priv->map; | |
230 | for (count = priv->map_items; count > 0; count--, map++) | |
231 | if (snd_ctl_elem_id_compare_set(id, &map->map_id) == 0) | |
232 | return map; | |
233 | return NULL; | |
234 | } | |
235 | ||
236 | static int remap_id_to_child(snd_ctl_remap_t *priv, snd_ctl_elem_id_t *id, snd_ctl_remap_id_t **_rid) | |
237 | { | |
238 | snd_ctl_remap_id_t *rid; | |
239 | snd_ctl_numid_t *numid; | |
240 | ||
241 | debug_id(id, "%s enter\n", __func__); | |
242 | rid = remap_find_id_app(priv, id); | |
243 | if (rid) { | |
244 | if (rid->id_app.numid == 0) { | |
245 | numid = remap_find_numid_app(priv, id->numid); | |
246 | if (numid) { | |
247 | rid->id_child.numid = numid->numid_child; | |
248 | rid->id_app.numid = numid->numid_app; | |
249 | } | |
250 | } | |
251 | *id = rid->id_child; | |
252 | } else { | |
253 | if (remap_find_id_child(priv, id)) | |
254 | return -ENOENT; | |
255 | numid = remap_find_numid_app(priv, id->numid); | |
256 | if (numid) | |
257 | id->numid = numid->numid_child; | |
258 | else | |
259 | id->numid = 0; | |
260 | } | |
261 | *_rid = rid; | |
262 | debug_id(id, "%s leave\n", __func__); | |
263 | return 0; | |
264 | } | |
265 | ||
266 | static int remap_id_to_app(snd_ctl_remap_t *priv, snd_ctl_elem_id_t *id, snd_ctl_remap_id_t *rid, int err) | |
267 | { | |
268 | snd_ctl_numid_t *numid; | |
269 | ||
270 | if (rid) { | |
271 | if (err >= 0 && rid->id_app.numid == 0) { | |
272 | numid = remap_numid_child_new(priv, id->numid); | |
273 | if (numid == NULL) | |
274 | return -EIO; | |
275 | rid->id_child.numid = numid->numid_child; | |
276 | rid->id_app.numid = numid->numid_app; | |
277 | } | |
278 | *id = rid->id_app; | |
279 | } else { | |
280 | if (err >= 0) { | |
281 | numid = remap_find_numid_child(priv, id->numid); | |
282 | if (numid == NULL) | |
283 | return -EIO; | |
284 | id->numid = numid->numid_app; | |
285 | } | |
286 | } | |
287 | return err; | |
288 | } | |
289 | ||
290 | static void remap_free(snd_ctl_remap_t *priv) | |
291 | { | |
292 | size_t idx1, idx2; | |
293 | snd_ctl_map_t *map; | |
294 | ||
295 | for (idx1 = 0; idx1 < priv->map_items; idx1++) { | |
296 | map = &priv->map[idx1]; | |
297 | for (idx2 = 0; idx2 < map->controls_items; idx2++) | |
298 | free(map->controls[idx2].channel_map); | |
299 | free(map->controls); | |
300 | } | |
301 | free(priv->map_read_queue); | |
302 | free(priv->map); | |
303 | free(priv->remap); | |
304 | free(priv->numid); | |
305 | free(priv); | |
306 | } | |
307 | ||
308 | static int snd_ctl_remap_close(snd_ctl_t *ctl) | |
309 | { | |
310 | snd_ctl_remap_t *priv = ctl->private_data; | |
311 | int err = snd_ctl_close(priv->child); | |
312 | remap_free(priv); | |
313 | return err; | |
314 | } | |
315 | ||
316 | static int snd_ctl_remap_nonblock(snd_ctl_t *ctl, int nonblock) | |
317 | { | |
318 | snd_ctl_remap_t *priv = ctl->private_data; | |
319 | return snd_ctl_nonblock(priv->child, nonblock); | |
320 | } | |
321 | ||
322 | static int snd_ctl_remap_async(snd_ctl_t *ctl, int sig, pid_t pid) | |
323 | { | |
324 | snd_ctl_remap_t *priv = ctl->private_data; | |
325 | return snd_ctl_async(priv->child, sig, pid); | |
326 | } | |
327 | ||
328 | static int snd_ctl_remap_subscribe_events(snd_ctl_t *ctl, int subscribe) | |
329 | { | |
330 | snd_ctl_remap_t *priv = ctl->private_data; | |
331 | return snd_ctl_subscribe_events(priv->child, subscribe); | |
332 | } | |
333 | ||
334 | static int snd_ctl_remap_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info) | |
335 | { | |
336 | snd_ctl_remap_t *priv = ctl->private_data; | |
337 | return snd_ctl_card_info(priv->child, info); | |
338 | } | |
339 | ||
340 | static int snd_ctl_remap_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t *list) | |
341 | { | |
342 | snd_ctl_remap_t *priv = ctl->private_data; | |
343 | snd_ctl_elem_id_t *id; | |
344 | snd_ctl_remap_id_t *rid; | |
345 | snd_ctl_numid_t *numid; | |
346 | snd_ctl_map_t *map; | |
347 | unsigned int index; | |
348 | size_t index2; | |
349 | int err; | |
350 | ||
351 | err = snd_ctl_elem_list(priv->child, list); | |
352 | if (err < 0) | |
353 | return err; | |
354 | for (index = 0; index < list->used; index++) { | |
355 | id = &list->pids[index]; | |
356 | rid = remap_find_id_child(priv, id); | |
357 | if (rid) { | |
358 | rid->id_app.numid = id->numid; | |
359 | *id = rid->id_app; | |
360 | } | |
361 | numid = remap_find_numid_child(priv, id->numid); | |
362 | if (numid == NULL) | |
363 | return -EIO; | |
364 | id->numid = numid->numid_app; | |
365 | } | |
366 | if (list->offset >= list->count + priv->map_items) | |
367 | return 0; | |
368 | index2 = 0; | |
369 | if (list->offset > list->count) | |
370 | index2 = list->offset - list->count; | |
371 | for ( ; index < list->space && index2 < priv->map_items; index2++, index++) { | |
372 | id = &list->pids[index]; | |
373 | map = &priv->map[index2]; | |
374 | *id = map->map_id; | |
375 | list->used++; | |
376 | } | |
377 | list->count += priv->map_items; | |
378 | return 0; | |
379 | } | |
380 | ||
381 | #define ACCESS_BITS(bits) \ | |
382 | (bits & (SNDRV_CTL_ELEM_ACCESS_READWRITE|\ | |
383 | SNDRV_CTL_ELEM_ACCESS_VOLATILE|\ | |
384 | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)) | |
385 | ||
386 | static int remap_map_elem_info(snd_ctl_remap_t *priv, snd_ctl_elem_info_t *info) | |
387 | { | |
388 | snd_ctl_map_t *map; | |
389 | snd_ctl_elem_info_t info2, info3; | |
390 | size_t item; | |
391 | unsigned int access; | |
392 | size_t count; | |
393 | int owner, err; | |
394 | ||
395 | map = remap_find_map_id(priv, &info->id); | |
396 | if (map == NULL) | |
397 | return -EREMAPNOTFOUND; | |
398 | debug_id(&info->id, "%s\n", __func__); | |
399 | assert(map->controls_items > 0); | |
400 | snd_ctl_elem_info_clear(&info2); | |
401 | info2.id = map->controls[0].id_child; | |
402 | debug_id(&info2.id, "%s controls[0]\n", __func__); | |
403 | err = snd_ctl_elem_info(priv->child, &info2); | |
404 | if (err < 0) | |
405 | return err; | |
406 | if (info2.type != SNDRV_CTL_ELEM_TYPE_BOOLEAN && | |
407 | info2.type != SNDRV_CTL_ELEM_TYPE_INTEGER && | |
408 | info2.type != SNDRV_CTL_ELEM_TYPE_INTEGER64 && | |
409 | info2.type != SNDRV_CTL_ELEM_TYPE_BYTES) | |
410 | return -EIO; | |
411 | map->controls[0].id_child.numid = info2.id.numid; | |
412 | map->type = info2.type; | |
413 | access = info2.access; | |
414 | owner = info2.owner; | |
415 | count = map->controls[0].channel_map_items; | |
416 | for (item = 1; item < map->controls_items; item++) { | |
417 | snd_ctl_elem_info_clear(&info3); | |
418 | info3.id = map->controls[item].id_child; | |
419 | debug_id(&info3.id, "%s controls[%zd]\n", __func__, item); | |
420 | err = snd_ctl_elem_info(priv->child, &info3); | |
421 | if (err < 0) | |
422 | return err; | |
423 | if (info2.type != info3.type) | |
424 | return -EIO; | |
425 | if (ACCESS_BITS(info2.access) != ACCESS_BITS(info3.access)) | |
426 | return -EIO; | |
427 | if (info2.type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || | |
428 | info2.type == SNDRV_CTL_ELEM_TYPE_INTEGER) { | |
429 | if (memcmp(&info2.value.integer, &info3.value.integer, sizeof(info2.value.integer))) | |
430 | return -EIO; | |
431 | } else if (info2.type == SNDRV_CTL_ELEM_TYPE_INTEGER64) { | |
432 | if (memcmp(&info2.value.integer64, &info3.value.integer64, sizeof(info2.value.integer64))) | |
433 | return -EIO; | |
434 | } | |
435 | access |= info3.access; | |
436 | if (owner == 0) | |
437 | owner = info3.owner; | |
438 | if (count < map->controls[item].channel_map_items) | |
439 | count = map->controls[item].channel_map_items; | |
440 | } | |
441 | snd_ctl_elem_info_clear(info); | |
442 | info->id = map->map_id; | |
443 | info->type = info2.type; | |
444 | info->access = access; | |
445 | info->count = count; | |
446 | if (info2.type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || | |
447 | info2.type == SNDRV_CTL_ELEM_TYPE_INTEGER) | |
448 | info->value.integer = info2.value.integer; | |
449 | else if (info2.type == SNDRV_CTL_ELEM_TYPE_INTEGER64) | |
450 | info->value.integer64 = info2.value.integer64; | |
451 | if (access & SNDRV_CTL_ELEM_ACCESS_LOCK) | |
452 | info->owner = owner; | |
453 | return 0; | |
454 | } | |
455 | ||
456 | static int snd_ctl_remap_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info) | |
457 | { | |
458 | snd_ctl_remap_t *priv = ctl->private_data; | |
459 | snd_ctl_remap_id_t *rid; | |
460 | int err; | |
461 | ||
462 | debug_id(&info->id, "%s\n", __func__); | |
463 | err = remap_map_elem_info(priv, info); | |
464 | if (err != -EREMAPNOTFOUND) | |
465 | return err; | |
466 | err = remap_id_to_child(priv, &info->id, &rid); | |
467 | if (err < 0) | |
468 | return err; | |
469 | err = snd_ctl_elem_info(priv->child, info); | |
470 | return remap_id_to_app(priv, &info->id, rid, err); | |
471 | } | |
472 | ||
473 | static int remap_map_elem_read(snd_ctl_remap_t *priv, snd_ctl_elem_value_t *control) | |
474 | { | |
475 | snd_ctl_map_t *map; | |
476 | struct snd_ctl_map_ctl *mctl; | |
477 | snd_ctl_elem_value_t control2; | |
478 | size_t item, index; | |
479 | int err; | |
480 | ||
481 | map = remap_find_map_id(priv, &control->id); | |
482 | if (map == NULL) | |
483 | return -EREMAPNOTFOUND; | |
484 | debug_id(&control->id, "%s\n", __func__); | |
485 | snd_ctl_elem_value_clear(control); | |
486 | control->id = map->map_id; | |
487 | for (item = 0; item < map->controls_items; item++) { | |
488 | mctl = &map->controls[item]; | |
489 | snd_ctl_elem_value_clear(&control2); | |
490 | control2.id = mctl->id_child; | |
491 | debug_id(&control2.id, "%s controls[%zd]\n", __func__, item); | |
492 | err = snd_ctl_elem_read(priv->child, &control2); | |
493 | if (err < 0) | |
494 | return err; | |
495 | if (map->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || | |
496 | map->type == SNDRV_CTL_ELEM_TYPE_INTEGER) { | |
497 | for (index = 0; index < mctl->channel_map_items; index++) { | |
498 | long src = mctl->channel_map[index]; | |
499 | if ((unsigned long)src < ARRAY_SIZE(control->value.integer.value)) | |
500 | control->value.integer.value[index] = control2.value.integer.value[src]; | |
501 | } | |
502 | } else if (map->type == SNDRV_CTL_ELEM_TYPE_INTEGER64) { | |
503 | for (index = 0; index < mctl->channel_map_items; index++) { | |
504 | long src = mctl->channel_map[index]; | |
505 | if ((unsigned long)src < ARRAY_SIZE(control->value.integer64.value)) | |
506 | control->value.integer64.value[index] = control2.value.integer64.value[src]; | |
507 | } | |
508 | } else if (map->type == SNDRV_CTL_ELEM_TYPE_BYTES) { | |
509 | for (index = 0; index < mctl->channel_map_items; index++) { | |
510 | long src = mctl->channel_map[index]; | |
511 | if ((unsigned long)src < ARRAY_SIZE(control->value.bytes.data)) | |
512 | control->value.bytes.data[index] = control2.value.bytes.data[src]; | |
513 | } | |
514 | } | |
515 | } | |
516 | return 0; | |
517 | } | |
518 | ||
519 | static int snd_ctl_remap_elem_read(snd_ctl_t *ctl, snd_ctl_elem_value_t *control) | |
520 | { | |
521 | snd_ctl_remap_t *priv = ctl->private_data; | |
522 | snd_ctl_remap_id_t *rid; | |
523 | int err; | |
524 | ||
525 | debug_id(&control->id, "%s\n", __func__); | |
526 | err = remap_map_elem_read(priv, control); | |
527 | if (err != -EREMAPNOTFOUND) | |
528 | return err; | |
529 | err = remap_id_to_child(priv, &control->id, &rid); | |
530 | if (err < 0) | |
531 | return err; | |
532 | err = snd_ctl_elem_read(priv->child, control); | |
533 | return remap_id_to_app(priv, &control->id, rid, err); | |
534 | } | |
535 | ||
536 | static int remap_map_elem_write(snd_ctl_remap_t *priv, snd_ctl_elem_value_t *control) | |
537 | { | |
538 | snd_ctl_map_t *map; | |
539 | struct snd_ctl_map_ctl *mctl; | |
540 | snd_ctl_elem_value_t control2; | |
541 | size_t item, index; | |
542 | int err, changes; | |
543 | ||
544 | map = remap_find_map_id(priv, &control->id); | |
545 | if (map == NULL) | |
546 | return -EREMAPNOTFOUND; | |
547 | debug_id(&control->id, "%s\n", __func__); | |
548 | control->id = map->map_id; | |
549 | for (item = 0; item < map->controls_items; item++) { | |
550 | mctl = &map->controls[item]; | |
551 | snd_ctl_elem_value_clear(&control2); | |
552 | control2.id = mctl->id_child; | |
553 | debug_id(&control2.id, "%s controls[%zd]\n", __func__, item); | |
554 | err = snd_ctl_elem_read(priv->child, &control2); | |
555 | if (err < 0) | |
556 | return err; | |
557 | changes = 0; | |
558 | if (map->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || | |
559 | map->type == SNDRV_CTL_ELEM_TYPE_INTEGER) { | |
560 | for (index = 0; index < mctl->channel_map_items; index++) { | |
561 | long dst = mctl->channel_map[index]; | |
562 | if ((unsigned long)dst < ARRAY_SIZE(control->value.integer.value)) { | |
563 | changes |= control2.value.integer.value[dst] != control->value.integer.value[index]; | |
564 | control2.value.integer.value[dst] = control->value.integer.value[index]; | |
565 | } | |
566 | } | |
567 | } else if (map->type == SNDRV_CTL_ELEM_TYPE_INTEGER64) { | |
568 | for (index = 0; index < mctl->channel_map_items; index++) { | |
569 | long dst = mctl->channel_map[index]; | |
570 | if ((unsigned long)dst < ARRAY_SIZE(control->value.integer64.value)) { | |
571 | changes |= control2.value.integer64.value[dst] != control->value.integer64.value[index]; | |
572 | control2.value.integer64.value[dst] = control->value.integer64.value[index]; | |
573 | } | |
574 | } | |
575 | } else if (map->type == SNDRV_CTL_ELEM_TYPE_BYTES) { | |
576 | for (index = 0; index < mctl->channel_map_items; index++) { | |
577 | long dst = mctl->channel_map[index]; | |
578 | if ((unsigned long)dst < ARRAY_SIZE(control->value.bytes.data)) { | |
579 | changes |= control2.value.bytes.data[dst] != control->value.bytes.data[index]; | |
580 | control2.value.bytes.data[dst] = control->value.bytes.data[index]; | |
581 | } | |
582 | } | |
583 | } | |
584 | debug_id(&control2.id, "%s changes %d\n", __func__, changes); | |
585 | if (changes > 0) { | |
586 | err = snd_ctl_elem_write(priv->child, &control2); | |
587 | if (err < 0) | |
588 | return err; | |
589 | } | |
590 | } | |
591 | return 0; | |
592 | } | |
593 | ||
594 | static int snd_ctl_remap_elem_write(snd_ctl_t *ctl, snd_ctl_elem_value_t *control) | |
595 | { | |
596 | snd_ctl_remap_t *priv = ctl->private_data; | |
597 | snd_ctl_remap_id_t *rid; | |
598 | int err; | |
599 | ||
600 | debug_id(&control->id, "%s\n", __func__); | |
601 | err = remap_map_elem_write(priv, control); | |
602 | if (err != -EREMAPNOTFOUND) | |
603 | return err; | |
604 | err = remap_id_to_child(priv, &control->id, &rid); | |
605 | if (err < 0) | |
606 | return err; | |
607 | err = snd_ctl_elem_write(priv->child, control); | |
608 | return remap_id_to_app(priv, &control->id, rid, err); | |
609 | } | |
610 | ||
611 | static int snd_ctl_remap_elem_lock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id) | |
612 | { | |
613 | snd_ctl_remap_t *priv = ctl->private_data; | |
614 | snd_ctl_remap_id_t *rid; | |
615 | int err; | |
616 | ||
617 | debug_id(id, "%s\n", __func__); | |
618 | err = remap_id_to_child(priv, id, &rid); | |
619 | if (err < 0) | |
620 | return err; | |
621 | err = snd_ctl_elem_lock(priv->child, id); | |
622 | return remap_id_to_app(priv, id, rid, err); | |
623 | } | |
624 | ||
625 | static int snd_ctl_remap_elem_unlock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id) | |
626 | { | |
627 | snd_ctl_remap_t *priv = ctl->private_data; | |
628 | snd_ctl_remap_id_t *rid; | |
629 | int err; | |
630 | ||
631 | debug_id(id, "%s\n", __func__); | |
632 | err = remap_id_to_child(priv, id, &rid); | |
633 | if (err < 0) | |
634 | return err; | |
635 | err = snd_ctl_elem_unlock(priv->child, id); | |
636 | return remap_id_to_app(priv, id, rid, err); | |
637 | } | |
638 | ||
639 | static int remap_get_map_numid(snd_ctl_remap_t *priv, struct snd_ctl_map_ctl *mctl) | |
640 | { | |
641 | snd_ctl_elem_info_t info; | |
642 | snd_ctl_numid_t *numid; | |
643 | int err; | |
644 | ||
645 | if (mctl->id_child.numid > 0) | |
646 | return 0; | |
647 | debug_id(&mctl->id_child, "%s get numid\n", __func__); | |
648 | snd_ctl_elem_info_clear(&info); | |
649 | info.id = mctl->id_child; | |
650 | err = snd_ctl_elem_info(priv->child, &info); | |
651 | if (err < 0) | |
652 | return err; | |
653 | numid = remap_find_numid_child(priv, info.id.numid); | |
654 | if (numid == NULL) | |
655 | return -EIO; | |
656 | mctl->id_child.numid = info.id.numid; | |
657 | return 0; | |
658 | } | |
659 | ||
660 | static int remap_map_elem_tlv(snd_ctl_remap_t *priv, int op_flag, unsigned int numid, | |
661 | unsigned int *tlv, unsigned int tlv_size) | |
662 | { | |
663 | snd_ctl_map_t *map; | |
664 | struct snd_ctl_map_ctl *mctl; | |
665 | size_t item; | |
666 | unsigned int *tlv2; | |
667 | int err; | |
668 | ||
669 | map = remap_find_map_numid(priv, numid); | |
670 | if (map == NULL) | |
671 | return -EREMAPNOTFOUND; | |
672 | if (op_flag != 0) /* read only */ | |
673 | return -ENXIO; | |
674 | debug("%s numid %d\n", __func__, numid); | |
675 | mctl = &map->controls[0]; | |
676 | err = remap_get_map_numid(priv, mctl); | |
677 | if (err < 0) | |
678 | return err; | |
679 | memset(tlv, 0, tlv_size); | |
680 | err = priv->child->ops->element_tlv(priv->child, op_flag, mctl->id_child.numid, tlv, tlv_size); | |
681 | if (err < 0) | |
682 | return err; | |
683 | tlv2 = malloc(tlv_size); | |
684 | if (tlv2 == NULL) | |
685 | return -ENOMEM; | |
686 | for (item = 1; item < map->controls_items; item++) { | |
687 | mctl = &map->controls[item]; | |
688 | err = remap_get_map_numid(priv, mctl); | |
689 | if (err < 0) { | |
690 | free(tlv2); | |
691 | return err; | |
692 | } | |
693 | memset(tlv2, 0, tlv_size); | |
694 | err = priv->child->ops->element_tlv(priv->child, op_flag, mctl->id_child.numid, tlv2, tlv_size); | |
695 | if (err < 0) { | |
696 | free(tlv2); | |
697 | return err; | |
698 | } | |
699 | if (memcmp(tlv, tlv2, tlv_size) != 0) { | |
700 | free(tlv2); | |
701 | return -EIO; | |
702 | } | |
703 | } | |
704 | free(tlv2); | |
705 | return 0; | |
706 | } | |
707 | ||
708 | static int snd_ctl_remap_elem_tlv(snd_ctl_t *ctl, int op_flag, | |
709 | unsigned int numid, | |
710 | unsigned int *tlv, unsigned int tlv_size) | |
711 | { | |
712 | snd_ctl_remap_t *priv = ctl->private_data; | |
713 | snd_ctl_numid_t *map_numid; | |
714 | int err; | |
715 | ||
716 | debug("%s: numid = %d, op_flag = %d\n", __func__, numid, op_flag); | |
717 | err = remap_map_elem_tlv(priv, op_flag, numid, tlv, tlv_size); | |
718 | if (err != -EREMAPNOTFOUND) | |
719 | return err; | |
720 | map_numid = remap_find_numid_app(priv, numid); | |
721 | if (map_numid == NULL) | |
722 | return -ENOENT; | |
723 | return priv->child->ops->element_tlv(priv->child, op_flag, map_numid->numid_child, tlv, tlv_size); | |
724 | } | |
725 | ||
726 | static int snd_ctl_remap_hwdep_next_device(snd_ctl_t *ctl, int * device) | |
727 | { | |
728 | snd_ctl_remap_t *priv = ctl->private_data; | |
729 | return snd_ctl_hwdep_next_device(priv->child, device); | |
730 | } | |
731 | ||
732 | static int snd_ctl_remap_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info) | |
733 | { | |
734 | snd_ctl_remap_t *priv = ctl->private_data; | |
735 | return snd_ctl_hwdep_info(priv->child, info); | |
736 | } | |
737 | ||
738 | static int snd_ctl_remap_pcm_next_device(snd_ctl_t *ctl, int * device) | |
739 | { | |
740 | snd_ctl_remap_t *priv = ctl->private_data; | |
741 | return snd_ctl_pcm_next_device(priv->child, device); | |
742 | } | |
743 | ||
744 | static int snd_ctl_remap_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info) | |
745 | { | |
746 | snd_ctl_remap_t *priv = ctl->private_data; | |
747 | return snd_ctl_pcm_info(priv->child, info); | |
748 | } | |
749 | ||
750 | static int snd_ctl_remap_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev) | |
751 | { | |
752 | snd_ctl_remap_t *priv = ctl->private_data; | |
753 | return snd_ctl_pcm_prefer_subdevice(priv->child, subdev); | |
754 | } | |
755 | ||
756 | static int snd_ctl_remap_rawmidi_next_device(snd_ctl_t *ctl, int * device) | |
757 | { | |
758 | snd_ctl_remap_t *priv = ctl->private_data; | |
759 | return snd_ctl_rawmidi_next_device(priv->child, device); | |
760 | } | |
761 | ||
762 | static int snd_ctl_remap_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info) | |
763 | { | |
764 | snd_ctl_remap_t *priv = ctl->private_data; | |
765 | return snd_ctl_rawmidi_info(priv->child, info); | |
766 | } | |
767 | ||
768 | static int snd_ctl_remap_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev) | |
769 | { | |
770 | snd_ctl_remap_t *priv = ctl->private_data; | |
771 | return snd_ctl_rawmidi_prefer_subdevice(priv->child, subdev); | |
772 | } | |
773 | ||
774 | static int snd_ctl_remap_set_power_state(snd_ctl_t *ctl, unsigned int state) | |
775 | { | |
776 | snd_ctl_remap_t *priv = ctl->private_data; | |
777 | return snd_ctl_set_power_state(priv->child, state); | |
778 | } | |
779 | ||
780 | static int snd_ctl_remap_get_power_state(snd_ctl_t *ctl, unsigned int *state) | |
781 | { | |
782 | snd_ctl_remap_t *priv = ctl->private_data; | |
783 | return snd_ctl_get_power_state(priv->child, state); | |
784 | } | |
785 | ||
786 | static void _next_ptr(size_t *ptr, size_t count) | |
787 | { | |
788 | *ptr = (*ptr + 1) % count; | |
789 | } | |
790 | ||
791 | static void remap_event_for_all_map_controls(snd_ctl_remap_t *priv, | |
792 | snd_ctl_elem_id_t *id, | |
793 | unsigned int event_mask) | |
794 | { | |
795 | size_t count, index, head; | |
796 | snd_ctl_map_t *map; | |
797 | struct snd_ctl_map_ctl *mctl; | |
798 | int found; | |
799 | ||
800 | if (event_mask == SNDRV_CTL_EVENT_MASK_REMOVE) | |
801 | event_mask = SNDRV_CTL_EVENT_MASK_INFO; | |
802 | map = priv->map; | |
803 | for (count = priv->map_items; count > 0; count--, map++) { | |
804 | for (index = 0; index < map->controls_items; index++) { | |
805 | mctl = &map->controls[index]; | |
806 | if (mctl->id_child.numid == 0) { | |
807 | if (snd_ctl_elem_id_compare_set(id, &mctl->id_child)) | |
808 | continue; | |
809 | mctl->id_child.numid = id->numid; | |
810 | } | |
811 | if (id->numid != mctl->id_child.numid) | |
812 | continue; | |
813 | debug_id(&map->map_id, "%s found (all)\n", __func__); | |
814 | map->event_mask |= event_mask; | |
815 | found = 0; | |
816 | for (head = priv->map_read_queue_head; | |
817 | head != priv->map_read_queue_tail; | |
818 | _next_ptr(&head, priv->map_items)) | |
819 | if (priv->map_read_queue[head] == map) { | |
820 | found = 1; | |
821 | break; | |
822 | } | |
823 | if (found) | |
824 | continue; | |
825 | debug_id(&map->map_id, "%s marking for read\n", __func__); | |
826 | priv->map_read_queue[priv->map_read_queue_tail] = map; | |
827 | _next_ptr(&priv->map_read_queue_tail, priv->map_items); | |
828 | } | |
829 | } | |
830 | } | |
831 | ||
832 | static int snd_ctl_remap_read(snd_ctl_t *ctl, snd_ctl_event_t *event) | |
833 | { | |
834 | snd_ctl_remap_t *priv = ctl->private_data; | |
835 | snd_ctl_remap_id_t *rid; | |
836 | snd_ctl_numid_t *numid; | |
837 | snd_ctl_map_t *map; | |
838 | int err; | |
839 | ||
840 | if (priv->map_read_queue_head != priv->map_read_queue_tail) { | |
841 | map = priv->map_read_queue[priv->map_read_queue_head]; | |
842 | _next_ptr(&priv->map_read_queue_head, priv->map_items); | |
843 | memset(event, 0, sizeof(*event)); | |
844 | event->type = SNDRV_CTL_EVENT_ELEM; | |
845 | event->data.elem.mask = map->event_mask; | |
846 | event->data.elem.id = map->map_id; | |
847 | map->event_mask = 0; | |
848 | debug_id(&map->map_id, "%s queue read\n", __func__); | |
849 | return 1; | |
850 | } | |
851 | err = snd_ctl_read(priv->child, event); | |
852 | if (err < 0 || event->type != SNDRV_CTL_EVENT_ELEM) | |
853 | return err; | |
854 | if (event->data.elem.mask == SNDRV_CTL_EVENT_MASK_REMOVE || | |
855 | (event->data.elem.mask & (SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO | | |
856 | SNDRV_CTL_EVENT_MASK_ADD | SNDRV_CTL_EVENT_MASK_TLV)) != 0) { | |
857 | debug_id(&event->data.elem.id, "%s event mask 0x%x\n", __func__, event->data.elem.mask); | |
858 | remap_event_for_all_map_controls(priv, &event->data.elem.id, event->data.elem.mask); | |
859 | rid = remap_find_id_child(priv, &event->data.elem.id); | |
860 | if (rid) { | |
861 | if (rid->id_child.numid == 0) { | |
862 | numid = remap_find_numid_child(priv, event->data.elem.id.numid); | |
863 | if (numid == NULL) | |
864 | return -EIO; | |
865 | rid->id_child.numid = numid->numid_child; | |
866 | rid->id_app.numid = numid->numid_app; | |
867 | } | |
868 | event->data.elem.id = rid->id_app; | |
869 | } else { | |
870 | numid = remap_find_numid_child(priv, event->data.elem.id.numid); | |
871 | if (numid == NULL) | |
872 | return -EIO; | |
873 | event->data.elem.id.numid = numid->numid_app; | |
874 | } | |
875 | } | |
876 | return err; | |
877 | } | |
878 | ||
879 | static const snd_ctl_ops_t snd_ctl_remap_ops = { | |
880 | .close = snd_ctl_remap_close, | |
881 | .nonblock = snd_ctl_remap_nonblock, | |
882 | .async = snd_ctl_remap_async, | |
883 | .subscribe_events = snd_ctl_remap_subscribe_events, | |
884 | .card_info = snd_ctl_remap_card_info, | |
885 | .element_list = snd_ctl_remap_elem_list, | |
886 | .element_info = snd_ctl_remap_elem_info, | |
887 | .element_read = snd_ctl_remap_elem_read, | |
888 | .element_write = snd_ctl_remap_elem_write, | |
889 | .element_lock = snd_ctl_remap_elem_lock, | |
890 | .element_unlock = snd_ctl_remap_elem_unlock, | |
891 | .element_tlv = snd_ctl_remap_elem_tlv, | |
892 | .hwdep_next_device = snd_ctl_remap_hwdep_next_device, | |
893 | .hwdep_info = snd_ctl_remap_hwdep_info, | |
894 | .pcm_next_device = snd_ctl_remap_pcm_next_device, | |
895 | .pcm_info = snd_ctl_remap_pcm_info, | |
896 | .pcm_prefer_subdevice = snd_ctl_remap_pcm_prefer_subdevice, | |
897 | .rawmidi_next_device = snd_ctl_remap_rawmidi_next_device, | |
898 | .rawmidi_info = snd_ctl_remap_rawmidi_info, | |
899 | .rawmidi_prefer_subdevice = snd_ctl_remap_rawmidi_prefer_subdevice, | |
900 | .set_power_state = snd_ctl_remap_set_power_state, | |
901 | .get_power_state = snd_ctl_remap_get_power_state, | |
902 | .read = snd_ctl_remap_read, | |
903 | }; | |
904 | ||
905 | static int add_to_remap(snd_ctl_remap_t *priv, | |
906 | snd_ctl_elem_id_t *child, | |
907 | snd_ctl_elem_id_t *app) | |
908 | { | |
909 | snd_ctl_remap_id_t *rid; | |
910 | ||
911 | if (priv->remap_alloc == priv->remap_items) { | |
912 | rid = realloc(priv->remap, (priv->remap_alloc + 16) * sizeof(*rid)); | |
913 | if (rid == NULL) | |
914 | return -ENOMEM; | |
915 | memset(rid + priv->remap_alloc, 0, sizeof(*rid) * 16); | |
916 | priv->remap_alloc += 16; | |
917 | priv->remap = rid; | |
918 | } | |
919 | rid = &priv->remap[priv->remap_items++]; | |
920 | rid->id_child = *child; | |
921 | rid->id_app = *app; | |
922 | debug_id(&rid->id_child, "%s remap child\n", __func__); | |
923 | debug_id(&rid->id_app, "%s remap app\n", __func__); | |
924 | return 0; | |
925 | } | |
926 | ||
927 | static int parse_remap(snd_ctl_remap_t *priv, snd_config_t *conf) | |
928 | { | |
929 | snd_config_iterator_t i, next; | |
930 | snd_ctl_elem_id_t child, app; | |
931 | int err; | |
932 | ||
933 | if (conf == NULL) | |
934 | return 0; | |
935 | snd_config_for_each(i, next, conf) { | |
936 | snd_config_t *n = snd_config_iterator_entry(i); | |
937 | const char *id, *str; | |
938 | if (snd_config_get_id(n, &id) < 0) | |
939 | continue; | |
940 | if (snd_config_get_string(n, &str) < 0) { | |
941 | SNDERR("expected string with the target control id!"); | |
942 | return -EINVAL; | |
943 | } | |
944 | snd_ctl_elem_id_clear(&app); | |
945 | err = snd_ctl_ascii_elem_id_parse(&app, str); | |
946 | if (err < 0) { | |
947 | SNDERR("unable to parse target id '%s'!", str); | |
948 | return -EINVAL; | |
949 | } | |
950 | if (remap_find_id_app(priv, &app)) { | |
951 | SNDERR("duplicate target id '%s'!", id); | |
952 | return -EINVAL; | |
953 | } | |
954 | snd_ctl_elem_id_clear(&child); | |
955 | err = snd_ctl_ascii_elem_id_parse(&child, id); | |
956 | if (err < 0) { | |
957 | SNDERR("unable to parse source id '%s'!", id); | |
958 | return -EINVAL; | |
959 | } | |
960 | if (remap_find_id_child(priv, &app)) { | |
961 | SNDERR("duplicate source id '%s'!", id); | |
962 | return -EINVAL; | |
963 | } | |
964 | err = add_to_remap(priv, &child, &app); | |
965 | if (err < 0) | |
966 | return err; | |
967 | } | |
968 | ||
969 | return 0; | |
970 | } | |
971 | ||
972 | static int new_map(snd_ctl_remap_t *priv, snd_ctl_map_t **_map, snd_ctl_elem_id_t *id) | |
973 | { | |
974 | snd_ctl_map_t *map; | |
975 | snd_ctl_numid_t *numid; | |
976 | ||
977 | if (priv->map_alloc == priv->map_items) { | |
978 | map = realloc(priv->map, (priv->map_alloc + 16) * sizeof(*map)); | |
979 | if (map == NULL) | |
980 | return -ENOMEM; | |
981 | memset(map + priv->map_alloc, 0, sizeof(*map) * 16); | |
982 | priv->map_alloc += 16; | |
983 | priv->map = map; | |
984 | } | |
985 | map = &priv->map[priv->map_items++]; | |
986 | map->map_id = *id; | |
987 | numid = remap_numid_new(priv, 0, ++priv->numid_app_last); | |
988 | if (numid == NULL) | |
989 | return -ENOMEM; | |
990 | map->map_id.numid = numid->numid_app; | |
991 | debug_id(&map->map_id, "%s created\n", __func__); | |
992 | *_map = map; | |
993 | return 0; | |
994 | } | |
995 | ||
996 | static int add_ctl_to_map(snd_ctl_map_t *map, struct snd_ctl_map_ctl **_mctl, snd_ctl_elem_id_t *id) | |
997 | { | |
998 | struct snd_ctl_map_ctl *mctl; | |
999 | ||
1000 | if (map->controls_alloc == map->controls_items) { | |
1001 | mctl = realloc(map->controls, (map->controls_alloc + 4) * sizeof(*mctl)); | |
1002 | if (mctl == NULL) | |
1003 | return -ENOMEM; | |
1004 | memset(mctl + map->controls_alloc, 0, sizeof(*mctl) * 4); | |
1005 | map->controls_alloc += 4; | |
1006 | map->controls = mctl; | |
1007 | } | |
1008 | mctl = &map->controls[map->controls_items++]; | |
1009 | mctl->id_child = *id; | |
1010 | *_mctl = mctl; | |
1011 | return 0; | |
1012 | } | |
1013 | ||
1014 | static int add_chn_to_map(struct snd_ctl_map_ctl *mctl, long idx, long val) | |
1015 | { | |
1016 | size_t off; | |
1017 | long *map; | |
1018 | ||
1019 | if (mctl->channel_map_alloc <= (size_t)idx) { | |
1020 | map = realloc(mctl->channel_map, (idx + 4) * sizeof(*map)); | |
1021 | if (map == NULL) | |
1022 | return -ENOMEM; | |
1023 | mctl->channel_map = map; | |
1024 | off = mctl->channel_map_alloc; | |
1025 | mctl->channel_map_alloc = idx + 4; | |
1026 | for ( ; off < mctl->channel_map_alloc; off++) | |
1027 | map[off] = -1; | |
1028 | } | |
1029 | if ((size_t)idx >= mctl->channel_map_items) | |
1030 | mctl->channel_map_items = idx + 1; | |
1031 | mctl->channel_map[idx] = val; | |
1032 | return 0; | |
1033 | } | |
1034 | ||
1035 | static int parse_map_vindex(struct snd_ctl_map_ctl *mctl, snd_config_t *conf) | |
1036 | { | |
1037 | snd_config_iterator_t i, next; | |
1038 | int err; | |
1039 | ||
1040 | snd_config_for_each(i, next, conf) { | |
1041 | snd_config_t *n = snd_config_iterator_entry(i); | |
1042 | long idx = -1, chn = -1; | |
1043 | const char *id; | |
1044 | if (snd_config_get_id(n, &id) < 0) | |
1045 | continue; | |
1046 | if (safe_strtol(id, &idx) || snd_config_get_integer(n, &chn)) { | |
1047 | SNDERR("Wrong channel mapping (%ld -> %ld)", idx, chn); | |
1048 | return -EINVAL; | |
1049 | } | |
1050 | err = add_chn_to_map(mctl, idx, chn); | |
1051 | if (err < 0) | |
1052 | return err; | |
1053 | } | |
1054 | ||
1055 | return 0; | |
1056 | } | |
1057 | ||
1058 | static int parse_map_config(struct snd_ctl_map_ctl *mctl, snd_config_t *conf) | |
1059 | { | |
1060 | snd_config_iterator_t i, next; | |
1061 | int err; | |
1062 | ||
1063 | snd_config_for_each(i, next, conf) { | |
1064 | snd_config_t *n = snd_config_iterator_entry(i); | |
1065 | const char *id; | |
1066 | if (snd_config_get_id(n, &id) < 0) | |
1067 | continue; | |
1068 | if (strcmp(id, "vindex") == 0) { | |
1069 | err = parse_map_vindex(mctl, n); | |
1070 | if (err < 0) | |
1071 | return err; | |
1072 | } | |
1073 | } | |
1074 | return 0; | |
1075 | } | |
1076 | ||
1077 | static int parse_map1(snd_ctl_map_t *map, snd_config_t *conf) | |
1078 | { | |
1079 | snd_config_iterator_t i, next; | |
1080 | snd_ctl_elem_id_t cid; | |
1081 | struct snd_ctl_map_ctl *mctl; | |
1082 | int err; | |
1083 | ||
1084 | snd_config_for_each(i, next, conf) { | |
1085 | snd_config_t *n = snd_config_iterator_entry(i); | |
1086 | const char *id; | |
1087 | if (snd_config_get_id(n, &id) < 0) | |
1088 | continue; | |
1089 | snd_ctl_elem_id_clear(&cid); | |
1090 | err = snd_ctl_ascii_elem_id_parse(&cid, id); | |
1091 | if (err < 0) { | |
1092 | SNDERR("unable to parse control id '%s'!", id); | |
1093 | return -EINVAL; | |
1094 | } | |
1095 | err = add_ctl_to_map(map, &mctl, &cid); | |
1096 | if (err < 0) | |
1097 | return err; | |
1098 | err = parse_map_config(mctl, n); | |
1099 | if (err < 0) | |
1100 | return err; | |
1101 | } | |
1102 | ||
1103 | return 0; | |
1104 | } | |
1105 | ||
1106 | static int parse_map(snd_ctl_remap_t *priv, snd_config_t *conf) | |
1107 | { | |
1108 | snd_config_iterator_t i, next; | |
1109 | snd_ctl_elem_id_t eid; | |
1110 | snd_ctl_map_t *map; | |
1111 | int err; | |
1112 | ||
1113 | if (conf == NULL) | |
1114 | return 0; | |
1115 | snd_config_for_each(i, next, conf) { | |
1116 | snd_config_t *n = snd_config_iterator_entry(i); | |
1117 | const char *id; | |
1118 | if (snd_config_get_id(n, &id) < 0) | |
1119 | continue; | |
1120 | snd_ctl_elem_id_clear(&eid); | |
1121 | err = snd_ctl_ascii_elem_id_parse(&eid, id); | |
1122 | if (err < 0) { | |
1123 | SNDERR("unable to parse id '%s'!", id); | |
1124 | return -EINVAL; | |
1125 | } | |
1126 | err = new_map(priv, &map, &eid); | |
1127 | if (err < 0) | |
1128 | return 0; | |
1129 | err = parse_map1(map, n); | |
1130 | if (err < 0) | |
1131 | return err; | |
1132 | } | |
1133 | ||
1134 | return 0; | |
1135 | } | |
1136 | ||
1137 | /** | |
1138 | * \brief Creates a new remap & map control handle | |
1139 | * \param handlep Returns created control handle | |
1140 | * \param name Name of control device | |
1141 | * \param remap Remap configuration | |
1142 | * \param map Map configuration | |
1143 | * \param mode Control handle mode | |
1144 | * \retval zero on success otherwise a negative error code | |
1145 | * \warning Using of this function might be dangerous in the sense | |
1146 | * of compatibility reasons. The prototype might be freely | |
1147 | * changed in future. | |
1148 | */ | |
1149 | int snd_ctl_remap_open(snd_ctl_t **handlep, const char *name, snd_config_t *remap, | |
1150 | snd_config_t *map, snd_ctl_t *child, int mode ATTRIBUTE_UNUSED) | |
1151 | { | |
1152 | snd_ctl_remap_t *priv; | |
1153 | snd_ctl_t *ctl; | |
1154 | int result, err; | |
1155 | ||
1156 | priv = calloc(1, sizeof(*priv)); | |
1157 | if (priv == NULL) | |
1158 | return -ENOMEM; | |
1159 | ||
1160 | err = parse_remap(priv, remap); | |
1161 | if (err < 0) { | |
1162 | result = err; | |
1163 | goto _err; | |
1164 | } | |
1165 | ||
1166 | err = parse_map(priv, map); | |
1167 | if (err < 0) { | |
1168 | result = err; | |
1169 | goto _err; | |
1170 | } | |
1171 | ||
1172 | /* no-op check, remove the plugin */ | |
1173 | if (priv->map_items == 0 && priv->remap_items == 0) { | |
1174 | remap_free(priv); | |
1175 | *handlep = child; | |
1176 | return 0; | |
1177 | } | |
1178 | ||
1179 | priv->map_read_queue = calloc(priv->map_items, sizeof(priv->map_read_queue[0])); | |
1180 | if (priv->map_read_queue == NULL) { | |
1181 | result = -ENOMEM; | |
1182 | goto _err; | |
1183 | } | |
1184 | ||
1185 | priv->numid_remap_active = priv->map_items > 0; | |
1186 | ||
1187 | priv->child = child; | |
1188 | err = snd_ctl_new(&ctl, SND_CTL_TYPE_REMAP, name); | |
1189 | if (err < 0) { | |
1190 | result = err; | |
1191 | goto _err; | |
1192 | } | |
1193 | ctl->ops = &snd_ctl_remap_ops; | |
1194 | ctl->private_data = priv; | |
1195 | ctl->poll_fd = child->poll_fd; | |
1196 | ||
1197 | *handlep = ctl; | |
1198 | return 0; | |
1199 | ||
1200 | _err: | |
1201 | remap_free(priv); | |
1202 | return result; | |
1203 | } | |
1204 | ||
1205 | /*! \page control_plugins | |
1206 | ||
1207 | \section control_plugins_remap Plugin: Remap & map | |
1208 | ||
1209 | This plugin can remap (rename) identifiers (except the numid part) for | |
1210 | a child control to another. The plugin can also merge the multiple | |
1211 | child controls to one or split one control to more. | |
1212 | ||
1213 | \code | |
1214 | ctl.name { | |
1215 | type remap # Route & Volume conversion PCM | |
1216 | child STR # Slave name | |
1217 | # or | |
1218 | child { # Slave definition | |
1219 | type STR | |
1220 | ... | |
1221 | } | |
1222 | remap { | |
1223 | # the ID strings are parsed in the amixer style like 'name="Headphone Playback Switch",index=2' | |
1224 | SRC_ID1_STR DST_ID1_STR | |
1225 | SRC_ID2_STR DST_ID2_STR | |
1226 | ... | |
1227 | } | |
1228 | map { | |
1229 | # join two stereo controls to one | |
1230 | CREATE_ID1_STR { | |
1231 | SRC_ID1_STR { | |
1232 | vindex.0 0 # source channel 0 to merged channel 0 | |
1233 | vindex.1 1 | |
1234 | } | |
1235 | SRC_ID2_STR { | |
1236 | vindex.2 0 | |
1237 | vindex.3 1 # source channel 1 to merged channel 3 | |
1238 | } | |
1239 | } | |
1240 | # split stereo to mono | |
1241 | CREATE_ID2_STR { | |
1242 | SRC_ID3_STR { | |
1243 | vindex.0 0 # stereo to mono (first channel) | |
1244 | } | |
1245 | } | |
1246 | CREATE_ID3_STR { | |
1247 | SRC_ID4_STR { | |
1248 | vindex.0 1 # stereo to mono (second channel) | |
1249 | } | |
1250 | } | |
1251 | } | |
1252 | } | |
1253 | \endcode | |
1254 | ||
1255 | \subsection control_plugins_route_funcref Function reference | |
1256 | ||
1257 | <UL> | |
1258 | <LI>snd_ctl_remap_open() | |
1259 | <LI>_snd_ctl_remap_open() | |
1260 | </UL> | |
1261 | ||
1262 | */ | |
1263 | ||
1264 | /** | |
1265 | * \brief Creates a new remap & map control plugin | |
1266 | * \param handlep Returns created control handle | |
1267 | * \param name Name of control | |
1268 | * \param root Root configuration node | |
1269 | * \param conf Configuration node with Route & Volume PCM description | |
1270 | * \param mode Control handle mode | |
1271 | * \retval zero on success otherwise a negative error code | |
1272 | * \warning Using of this function might be dangerous in the sense | |
1273 | * of compatibility reasons. The prototype might be freely | |
1274 | * changed in future. | |
1275 | */ | |
1276 | int _snd_ctl_remap_open(snd_ctl_t **handlep, char *name, snd_config_t *root, snd_config_t *conf, int mode) | |
1277 | { | |
1278 | snd_config_iterator_t i, next; | |
1279 | snd_config_t *child = NULL; | |
1280 | snd_config_t *remap = NULL; | |
1281 | snd_config_t *map = NULL; | |
1282 | snd_ctl_t *cctl; | |
1283 | int err; | |
1284 | ||
1285 | snd_config_for_each(i, next, conf) { | |
1286 | snd_config_t *n = snd_config_iterator_entry(i); | |
1287 | const char *id; | |
1288 | if (snd_config_get_id(n, &id) < 0) | |
1289 | continue; | |
1290 | if (_snd_conf_generic_id(id)) | |
1291 | continue; | |
1292 | if (strcmp(id, "remap") == 0) { | |
1293 | remap = n; | |
1294 | continue; | |
1295 | } | |
1296 | if (strcmp(id, "map") == 0) { | |
1297 | map = n; | |
1298 | continue; | |
1299 | } | |
1300 | if (strcmp(id, "child") == 0) { | |
1301 | child = n; | |
1302 | continue; | |
1303 | } | |
1304 | SNDERR("Unknown field %s", id); | |
1305 | return -EINVAL; | |
1306 | } | |
1307 | if (!child) { | |
1308 | SNDERR("child is not defined"); | |
1309 | return -EINVAL; | |
1310 | } | |
1311 | err = _snd_ctl_open_child(&cctl, root, child, mode, conf); | |
1312 | if (err < 0) | |
1313 | return err; | |
1314 | /* no-op, remove the plugin */ | |
1315 | if (!remap && !map) { | |
1316 | *handlep = cctl; | |
1317 | return 0; | |
1318 | } | |
1319 | err = snd_ctl_remap_open(handlep, name, remap, map, cctl, mode); | |
1320 | if (err < 0) | |
1321 | snd_ctl_close(cctl); | |
1322 | return err; | |
1323 | } | |
1324 | SND_DLSYM_BUILD_VERSION(_snd_ctl_remap_open, SND_CONTROL_DLSYM_VERSION); |
541 | 541 | if (snd_config_get_id(n, &id) < 0) |
542 | 542 | continue; |
543 | 543 | if (_snd_conf_generic_id(id)) |
544 | continue; | |
544 | 545 | if (strcmp(id, "server") == 0) { |
545 | 546 | err = snd_config_get_string(n, &server); |
546 | 547 | if (err < 0) { |
20 | 20 | #ifndef PIC |
21 | 21 | |
22 | 22 | extern const char *_snd_module_control_hw; |
23 | extern const char *_snd_module_control_empty; | |
24 | extern const char *_snd_module_control_remap; | |
23 | 25 | extern const char *_snd_module_control_shm; |
24 | 26 | extern const char *_snd_module_control_ext; |
25 | 27 | |
26 | 28 | static const char **snd_control_open_objects[] = { |
27 | 29 | &_snd_module_control_hw, |
30 | &_snd_module_control_empty, | |
28 | 31 | #include "ctl_symbols_list.c" |
29 | 32 | }; |
30 | 33 |
115 | 115 | */ |
116 | 116 | char *snd_ctl_ascii_elem_id_get(snd_ctl_elem_id_t *id) |
117 | 117 | { |
118 | unsigned int index, device, subdevice; | |
118 | unsigned int numid, index, device, subdevice; | |
119 | 119 | char buf[256], buf1[32]; |
120 | ||
121 | snprintf(buf, sizeof(buf), "numid=%u,iface=%s,name='%s'", | |
122 | snd_ctl_elem_id_get_numid(id), | |
123 | snd_ctl_elem_iface_name( | |
124 | snd_ctl_elem_id_get_interface(id)), | |
125 | snd_ctl_elem_id_get_name(id)); | |
120 | const char *iface; | |
121 | ||
122 | numid = snd_ctl_elem_id_get_numid(id); | |
123 | iface = snd_ctl_elem_iface_name(snd_ctl_elem_id_get_interface(id)); | |
124 | if (numid > 0) { | |
125 | snprintf(buf, sizeof(buf), "numid=%u,iface=%s,name='%s'", | |
126 | numid, iface, snd_ctl_elem_id_get_name(id)); | |
127 | } else { | |
128 | snprintf(buf, sizeof(buf), "iface=%s,name='%s'", | |
129 | iface, snd_ctl_elem_id_get_name(id)); | |
130 | } | |
126 | 131 | buf[sizeof(buf)-1] = '\0'; |
127 | 132 | index = snd_ctl_elem_id_get_index(id); |
128 | 133 | device = snd_ctl_elem_id_get_device(id); |
41 | 41 | #ifndef PIC |
42 | 42 | struct snd_dlsym_link *snd_dlsym_start = NULL; |
43 | 43 | #endif |
44 | #ifdef DL_ORIGIN_AVAILABLE | |
45 | 44 | static int snd_plugin_dir_set = 0; |
46 | 45 | static char *snd_plugin_dir = NULL; |
47 | 46 | #endif |
48 | #endif | |
49 | ||
50 | #if defined(DL_ORIGIN_AVAILABLE) && defined(HAVE_LIBPTHREAD) | |
47 | ||
48 | #ifdef HAVE_LIBPTHREAD | |
51 | 49 | static pthread_mutex_t snd_dlpath_mutex = PTHREAD_MUTEX_INITIALIZER; |
52 | 50 | |
53 | 51 | static inline void snd_dlpath_lock(void) |
441 | 439 | free(c); |
442 | 440 | } |
443 | 441 | snd_dlobj_unlock(); |
444 | #ifdef DL_ORIGIN_AVAILABLE | |
445 | 442 | snd_dlpath_lock(); |
446 | 443 | snd_plugin_dir_set = 0; |
447 | 444 | free(snd_plugin_dir); |
448 | 445 | snd_plugin_dir = NULL; |
449 | 446 | snd_dlpath_unlock(); |
450 | #endif | |
451 | } | |
452 | #endif | |
447 | } | |
448 | #endif |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
296 | 296 | prefix = @prefix@ |
297 | 297 | program_transform_name = @program_transform_name@ |
298 | 298 | psdir = @psdir@ |
299 | runstatedir = @runstatedir@ | |
299 | 300 | sbindir = @sbindir@ |
300 | 301 | sharedstatedir = @sharedstatedir@ |
301 | 302 | srcdir = @srcdir@ |
150 | 150 | { |
151 | 151 | snd_config_iterator_t i, next; |
152 | 152 | long card = -1, device = 0; |
153 | const char *str; | |
154 | 153 | int err; |
155 | 154 | snd_config_for_each(i, next, conf) { |
156 | 155 | snd_config_t *n = snd_config_iterator_entry(i); |
160 | 159 | if (_snd_conf_generic_id(id)) |
161 | 160 | continue; |
162 | 161 | if (strcmp(id, "card") == 0) { |
163 | err = snd_config_get_integer(n, &card); | |
164 | if (err < 0) { | |
165 | err = snd_config_get_string(n, &str); | |
166 | if (err < 0) | |
167 | return -EINVAL; | |
168 | card = snd_card_get_index(str); | |
169 | if (card < 0) | |
170 | return card; | |
171 | } | |
162 | err = snd_config_get_card(n); | |
163 | if (err < 0) | |
164 | return err; | |
165 | card = err; | |
172 | 166 | continue; |
173 | 167 | } |
174 | 168 | if (strcmp(id, "device") == 0) { |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
302 | 302 | prefix = @prefix@ |
303 | 303 | program_transform_name = @program_transform_name@ |
304 | 304 | psdir = @psdir@ |
305 | runstatedir = @runstatedir@ | |
305 | 306 | sbindir = @sbindir@ |
306 | 307 | sharedstatedir = @sharedstatedir@ |
307 | 308 | srcdir = @srcdir@ |
906 | 906 | }; |
907 | 907 | #endif |
908 | 908 | |
909 | /* Return base length or 0 on failure */ | |
909 | /* Return base length */ | |
910 | 910 | static int base_len(const char *name, selem_ctl_type_t *type) |
911 | 911 | { |
912 | 912 | const struct suf *p; |
913 | 913 | size_t nlen = strlen(name); |
914 | p = suffixes; | |
915 | while (p->suffix) { | |
914 | ||
915 | /* exception: "Capture Volume" and "Capture Switch" */ | |
916 | if (!strcmp(name, "Capture Volume")) { | |
917 | *type = CTL_CAPTURE_VOLUME; | |
918 | return strlen("Capture"); | |
919 | } | |
920 | if (!strcmp(name, "Capture Switch")) { | |
921 | *type = CTL_CAPTURE_SWITCH; | |
922 | return strlen("Capture"); | |
923 | } | |
924 | ||
925 | for (p = suffixes; p->suffix; p++) { | |
916 | 926 | size_t slen = strlen(p->suffix); |
917 | 927 | size_t l; |
918 | 928 | if (nlen > slen) { |
923 | 933 | return l; |
924 | 934 | } |
925 | 935 | } |
926 | p++; | |
927 | 936 | } |
928 | 937 | |
929 | 938 | /* Special case - handle "Input Source" as a capture route. |
943 | 952 | return strlen(name); |
944 | 953 | } |
945 | 954 | } |
946 | return 0; | |
955 | ||
956 | *type = CTL_SINGLE; | |
957 | return strlen(name); | |
947 | 958 | } |
948 | 959 | |
949 | 960 | |
1604 | 1615 | static int simple_event_add(snd_mixer_class_t *class, snd_hctl_elem_t *helem) |
1605 | 1616 | { |
1606 | 1617 | const char *name = snd_hctl_elem_get_name(helem); |
1618 | selem_ctl_type_t type; | |
1619 | char ename[128]; | |
1607 | 1620 | size_t len; |
1608 | selem_ctl_type_t type = CTL_SINGLE; /* to shut up warning */ | |
1621 | ||
1609 | 1622 | if (snd_hctl_elem_get_interface(helem) != SND_CTL_ELEM_IFACE_MIXER) |
1610 | 1623 | return 0; |
1611 | 1624 | if (strcmp(name, "Capture Source") == 0) { |
1632 | 1645 | } |
1633 | 1646 | return 0; |
1634 | 1647 | } |
1648 | ||
1635 | 1649 | len = base_len(name, &type); |
1636 | if (len == 0) { | |
1637 | return simple_add1(class, name, helem, CTL_SINGLE, 0); | |
1638 | } else { | |
1639 | char ename[128]; | |
1640 | if (len >= sizeof(ename)) | |
1641 | len = sizeof(ename) - 1; | |
1642 | memcpy(ename, name, len); | |
1643 | ename[len] = 0; | |
1644 | /* exception: Capture Volume and Capture Switch */ | |
1645 | if (type == CTL_GLOBAL_VOLUME && !strcmp(ename, "Capture")) | |
1646 | type = CTL_CAPTURE_VOLUME; | |
1647 | else if (type == CTL_GLOBAL_SWITCH && !strcmp(ename, "Capture")) | |
1648 | type = CTL_CAPTURE_SWITCH; | |
1649 | return simple_add1(class, ename, helem, type, 0); | |
1650 | } | |
1650 | if (len >= sizeof(ename)) | |
1651 | len = sizeof(ename) - 1; | |
1652 | memcpy(ename, name, len); | |
1653 | ename[len] = 0; | |
1654 | ||
1655 | return simple_add1(class, ename, helem, type, 0); | |
1651 | 1656 | } |
1652 | 1657 | |
1653 | 1658 | static int simple_event_remove(snd_hctl_elem_t *helem, |
251 | 251 | size_t alloc; |
252 | 252 | unsigned char *buf; |
253 | 253 | |
254 | /* use 'size++' to allow to add the '\0' string terminator */ | |
255 | /* without reallocation */ | |
256 | size++; | |
254 | 257 | if (_free >= size) |
255 | 258 | return _free; |
256 | 259 | if (buffer->alloc == 0) |
349 | 352 | } |
350 | 353 | |
351 | 354 | /** |
355 | * \brief Returns the address of the buffer of a #SND_OUTPUT_BUFFER output handle. | |
356 | * \param output The output handle. | |
357 | * \param buf The functions puts the current address of the buffer at the | |
358 | * address specified by \p buf. | |
359 | * \return The current size of valid data in the buffer. | |
360 | * | |
361 | * The internal buffer is empty after this call. The caller has the responsibility | |
362 | * to clean the buffer using the free() call. | |
363 | */ | |
364 | size_t snd_output_buffer_steal(snd_output_t *output, char **buf) | |
365 | { | |
366 | snd_output_buffer_t *buffer = output->private_data; | |
367 | size_t size; | |
368 | *buf = (char *)buffer->buf; | |
369 | size = buffer->size; | |
370 | buffer->buf = NULL; | |
371 | buffer->alloc = 0; | |
372 | buffer->size = 0; | |
373 | return size; | |
374 | } | |
375 | ||
376 | /** | |
352 | 377 | * \brief Creates a new output object with an auto-extending memory buffer. |
353 | 378 | * \param outputp The function puts the pointer to the new output object |
354 | 379 | * at the address specified by \p outputp. |
376 | 401 | *outputp = output; |
377 | 402 | return 0; |
378 | 403 | } |
379 |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
439 | 439 | prefix = @prefix@ |
440 | 440 | program_transform_name = @program_transform_name@ |
441 | 441 | psdir = @psdir@ |
442 | runstatedir = @runstatedir@ | |
442 | 443 | sbindir = @sbindir@ |
443 | 444 | sharedstatedir = @sharedstatedir@ |
444 | 445 | srcdir = @srcdir@ |
2685 | 2685 | int err; |
2686 | 2686 | |
2687 | 2687 | assert(pcmp && name); |
2688 | err = snd_config_update_ref(&top); | |
2689 | if (err < 0) | |
2690 | return err; | |
2688 | if (_snd_is_ucm_device(name)) { | |
2689 | name = uc_mgr_alibcfg_by_device(&top, name); | |
2690 | if (name == NULL) | |
2691 | return -ENODEV; | |
2692 | } else { | |
2693 | err = snd_config_update_ref(&top); | |
2694 | if (err < 0) | |
2695 | return err; | |
2696 | } | |
2691 | 2697 | err = snd_pcm_open_noupdate(pcmp, top, name, stream, mode, 0); |
2692 | 2698 | snd_config_unref(top); |
2693 | 2699 | return err; |
7217 | 7223 | } |
7218 | 7224 | |
7219 | 7225 | #ifndef DOC_HIDDEN |
7220 | /* locked version */ | |
7221 | int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, | |
7222 | snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames) | |
7226 | int __snd_pcm_mmap_begin_generic(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, | |
7227 | snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames) | |
7223 | 7228 | { |
7224 | 7229 | snd_pcm_uframes_t cont; |
7225 | 7230 | snd_pcm_uframes_t f; |
7227 | 7232 | const snd_pcm_channel_area_t *xareas; |
7228 | 7233 | |
7229 | 7234 | assert(pcm && areas && offset && frames); |
7230 | ||
7231 | if (pcm->fast_ops->mmap_begin) | |
7232 | return pcm->fast_ops->mmap_begin(pcm->fast_op_arg, areas, offset, frames); | |
7233 | 7235 | |
7234 | 7236 | /* fallback for plugins that do not specify new callback */ |
7235 | 7237 | xareas = snd_pcm_mmap_areas(pcm); |
7248 | 7250 | f = cont; |
7249 | 7251 | *frames = f; |
7250 | 7252 | return 0; |
7253 | } | |
7254 | ||
7255 | /* locked version */ | |
7256 | int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, | |
7257 | snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames) | |
7258 | { | |
7259 | assert(pcm && areas && offset && frames); | |
7260 | ||
7261 | if (pcm->fast_ops->mmap_begin) | |
7262 | return pcm->fast_ops->mmap_begin(pcm->fast_op_arg, areas, offset, frames); | |
7263 | ||
7264 | return __snd_pcm_mmap_begin_generic(pcm, areas, offset, frames); | |
7251 | 7265 | } |
7252 | 7266 | #endif |
7253 | 7267 |
1833 | 1833 | continue; |
1834 | 1834 | } |
1835 | 1835 | if (strcmp(id, "card") == 0) { |
1836 | err = snd_config_get_integer(n, &card); | |
1837 | if (err < 0) { | |
1838 | err = snd_config_get_string(n, &str); | |
1839 | if (err < 0) { | |
1840 | SNDERR("Invalid type for %s", id); | |
1841 | return -EINVAL; | |
1842 | } | |
1843 | card = snd_card_get_index(str); | |
1844 | if (card < 0) { | |
1845 | SNDERR("Invalid value for %s", id); | |
1846 | return card; | |
1847 | } | |
1848 | } | |
1836 | err = snd_config_get_card(n); | |
1837 | if (err < 0) | |
1838 | return err; | |
1839 | card = err; | |
1849 | 1840 | continue; |
1850 | 1841 | } |
1851 | 1842 | if (strcmp(id, "device") == 0) { |
1865 | 1856 | continue; |
1866 | 1857 | } |
1867 | 1858 | } |
1868 | if (card < 0) | |
1869 | card = 0; | |
1870 | 1859 | if (device < 0) |
1871 | 1860 | device = 0; |
1872 | 1861 | if (subdevice < 0) |
2105 | 2094 | ((dmix->slave_hw_ptr / dmix->slave_period_size) * |
2106 | 2095 | dmix->slave_period_size); |
2107 | 2096 | } |
2097 | ||
2098 | int _snd_pcm_direct_new(snd_pcm_t **pcmp, snd_pcm_direct_t **_dmix, int type, | |
2099 | const char *name, struct snd_pcm_direct_open_conf *opts, | |
2100 | struct slave_params *params, snd_pcm_stream_t stream, int mode) | |
2101 | { | |
2102 | snd_pcm_direct_t *dmix; | |
2103 | int fail_sem_loop = 10; | |
2104 | int ret; | |
2105 | ||
2106 | dmix = calloc(1, sizeof(snd_pcm_direct_t)); | |
2107 | if (!dmix) | |
2108 | return -ENOMEM; | |
2109 | ||
2110 | ret = snd_pcm_direct_parse_bindings(dmix, params, opts->bindings); | |
2111 | if (ret < 0) { | |
2112 | free(dmix); | |
2113 | return ret; | |
2114 | } | |
2115 | ||
2116 | dmix->ipc_key = opts->ipc_key; | |
2117 | dmix->ipc_perm = opts->ipc_perm; | |
2118 | dmix->ipc_gid = opts->ipc_gid; | |
2119 | dmix->tstamp_type = opts->tstamp_type; | |
2120 | dmix->semid = -1; | |
2121 | dmix->shmid = -1; | |
2122 | dmix->shmptr = (void *) -1; | |
2123 | dmix->type = type; | |
2124 | ||
2125 | ret = snd_pcm_new(pcmp, type, name, stream, mode); | |
2126 | if (ret < 0) | |
2127 | goto _err_nosem; | |
2128 | ||
2129 | while (1) { | |
2130 | ret = snd_pcm_direct_semaphore_create_or_connect(dmix); | |
2131 | if (ret < 0) { | |
2132 | SNDERR("unable to create IPC semaphore"); | |
2133 | goto _err_nosem_free; | |
2134 | } | |
2135 | ret = snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT); | |
2136 | if (ret < 0) { | |
2137 | snd_pcm_direct_semaphore_discard(dmix); | |
2138 | if (--fail_sem_loop <= 0) | |
2139 | goto _err_nosem_free; | |
2140 | continue; | |
2141 | } | |
2142 | break; | |
2143 | } | |
2144 | ||
2145 | ret = snd_pcm_direct_shm_create_or_connect(dmix); | |
2146 | if (ret < 0) { | |
2147 | SNDERR("unable to create IPC shm instance"); | |
2148 | snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT); | |
2149 | goto _err_nosem_free; | |
2150 | } else { | |
2151 | *_dmix = dmix; | |
2152 | } | |
2153 | ||
2154 | return ret; | |
2155 | _err_nosem_free: | |
2156 | snd_pcm_free(*pcmp); | |
2157 | *pcmp = NULL; | |
2158 | _err_nosem: | |
2159 | free(dmix->bindings); | |
2160 | free(dmix); | |
2161 | return ret; | |
2162 | } |
364 | 364 | }; |
365 | 365 | |
366 | 366 | int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf, int stream, struct snd_pcm_direct_open_conf *rec); |
367 | ||
368 | int _snd_pcm_direct_new(snd_pcm_t **pcmp, snd_pcm_direct_t **_dmix, int type, | |
369 | const char *name, struct snd_pcm_direct_open_conf *opts, | |
370 | struct slave_params *params, snd_pcm_stream_t stream, int mode); |
487 | 487 | case SNDRV_PCM_STATE_DRAINING: |
488 | 488 | case SNDRV_PCM_STATE_RUNNING: |
489 | 489 | snd_pcm_dmix_sync_ptr0(pcm, status->hw_ptr); |
490 | status->delay += snd_pcm_mmap_playback_delay(pcm) | |
491 | + status->avail - dmix->spcm->buffer_size; | |
490 | status->delay = snd_pcm_mmap_playback_delay(pcm); | |
492 | 491 | break; |
493 | 492 | default: |
494 | 493 | break; |
495 | 494 | } |
496 | 495 | |
497 | 496 | status->state = snd_pcm_dmix_state(pcm); |
497 | status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */ | |
498 | 498 | status->trigger_tstamp = dmix->trigger_tstamp; |
499 | 499 | status->avail = snd_pcm_mmap_playback_avail(pcm); |
500 | 500 | status->avail_max = status->avail > dmix->avail_max ? status->avail : dmix->avail_max; |
517 | 517 | case SNDRV_PCM_STATE_PREPARED: |
518 | 518 | case SNDRV_PCM_STATE_SUSPENDED: |
519 | 519 | case STATE_RUN_PENDING: |
520 | *delayp = snd_pcm_mmap_playback_hw_avail(pcm); | |
520 | *delayp = snd_pcm_mmap_playback_delay(pcm); | |
521 | 521 | return 0; |
522 | 522 | case SNDRV_PCM_STATE_XRUN: |
523 | 523 | return -EPIPE; |
997 | 997 | snd_config_t *root, snd_config_t *sconf, |
998 | 998 | snd_pcm_stream_t stream, int mode) |
999 | 999 | { |
1000 | snd_pcm_t *pcm = NULL, *spcm = NULL; | |
1001 | snd_pcm_direct_t *dmix = NULL; | |
1000 | snd_pcm_t *pcm, *spcm = NULL; | |
1001 | snd_pcm_direct_t *dmix; | |
1002 | 1002 | int ret, first_instance; |
1003 | int fail_sem_loop = 10; | |
1004 | 1003 | |
1005 | 1004 | assert(pcmp); |
1006 | 1005 | |
1009 | 1008 | return -EINVAL; |
1010 | 1009 | } |
1011 | 1010 | |
1012 | dmix = calloc(1, sizeof(snd_pcm_direct_t)); | |
1013 | if (!dmix) { | |
1014 | ret = -ENOMEM; | |
1015 | goto _err_nosem; | |
1016 | } | |
1017 | ||
1018 | ret = snd_pcm_direct_parse_bindings(dmix, params, opts->bindings); | |
1011 | ret = _snd_pcm_direct_new(&pcm, &dmix, SND_PCM_TYPE_DMIX, name, opts, params, stream, mode); | |
1019 | 1012 | if (ret < 0) |
1020 | goto _err_nosem; | |
1021 | ||
1022 | dmix->ipc_key = opts->ipc_key; | |
1023 | dmix->ipc_perm = opts->ipc_perm; | |
1024 | dmix->ipc_gid = opts->ipc_gid; | |
1025 | dmix->tstamp_type = opts->tstamp_type; | |
1026 | dmix->semid = -1; | |
1027 | dmix->shmid = -1; | |
1028 | ||
1029 | ret = snd_pcm_new(&pcm, dmix->type = SND_PCM_TYPE_DMIX, name, stream, mode); | |
1030 | if (ret < 0) | |
1031 | goto _err; | |
1032 | ||
1033 | ||
1034 | while (1) { | |
1035 | ret = snd_pcm_direct_semaphore_create_or_connect(dmix); | |
1036 | if (ret < 0) { | |
1037 | SNDERR("unable to create IPC semaphore"); | |
1038 | goto _err_nosem; | |
1039 | } | |
1040 | ret = snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT); | |
1041 | if (ret < 0) { | |
1042 | snd_pcm_direct_semaphore_discard(dmix); | |
1043 | if (--fail_sem_loop <= 0) | |
1044 | goto _err_nosem; | |
1045 | continue; | |
1046 | } | |
1047 | break; | |
1048 | } | |
1049 | ||
1050 | first_instance = ret = snd_pcm_direct_shm_create_or_connect(dmix); | |
1051 | if (ret < 0) { | |
1052 | SNDERR("unable to create IPC shm instance"); | |
1053 | goto _err; | |
1054 | } | |
1055 | ||
1013 | return ret; | |
1014 | first_instance = ret; | |
1015 | ||
1056 | 1016 | pcm->ops = &snd_pcm_dmix_ops; |
1057 | 1017 | pcm->fast_ops = &snd_pcm_dmix_fast_ops; |
1058 | 1018 | pcm->private_data = dmix; |
1193 | 1153 | } else |
1194 | 1154 | snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT); |
1195 | 1155 | _err_nosem: |
1196 | if (dmix) { | |
1197 | free(dmix->bindings); | |
1198 | free(dmix); | |
1199 | } | |
1200 | if (pcm) | |
1201 | snd_pcm_free(pcm); | |
1156 | free(dmix->bindings); | |
1157 | free(dmix); | |
1158 | snd_pcm_free(pcm); | |
1202 | 1159 | return ret; |
1203 | 1160 | } |
1204 | 1161 |
236 | 236 | case SNDRV_PCM_STATE_DRAINING: |
237 | 237 | case SNDRV_PCM_STATE_RUNNING: |
238 | 238 | snd_pcm_dshare_sync_ptr0(pcm, status->hw_ptr); |
239 | status->delay += snd_pcm_mmap_playback_delay(pcm) | |
240 | + status->avail - dshare->spcm->buffer_size; | |
239 | status->delay += snd_pcm_mmap_playback_delay(pcm); | |
241 | 240 | break; |
242 | 241 | default: |
243 | 242 | break; |
244 | 243 | } |
245 | 244 | status->state = snd_pcm_dshare_state(pcm); |
245 | status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */ | |
246 | 246 | status->trigger_tstamp = dshare->trigger_tstamp; |
247 | 247 | status->avail = snd_pcm_mmap_playback_avail(pcm); |
248 | 248 | status->avail_max = status->avail > dshare->avail_max ? status->avail : dshare->avail_max; |
289 | 289 | case SNDRV_PCM_STATE_PREPARED: |
290 | 290 | case SNDRV_PCM_STATE_SUSPENDED: |
291 | 291 | case STATE_RUN_PENDING: |
292 | *delayp = snd_pcm_mmap_playback_hw_avail(pcm); | |
292 | *delayp = snd_pcm_mmap_playback_delay(pcm); | |
293 | 293 | return 0; |
294 | 294 | case SNDRV_PCM_STATE_XRUN: |
295 | 295 | return -EPIPE; |
689 | 689 | snd_config_t *root, snd_config_t *sconf, |
690 | 690 | snd_pcm_stream_t stream, int mode) |
691 | 691 | { |
692 | snd_pcm_t *pcm = NULL, *spcm = NULL; | |
693 | snd_pcm_direct_t *dshare = NULL; | |
692 | snd_pcm_t *pcm, *spcm = NULL; | |
693 | snd_pcm_direct_t *dshare; | |
694 | 694 | int ret, first_instance; |
695 | 695 | unsigned int chn; |
696 | int fail_sem_loop = 10; | |
697 | 696 | |
698 | 697 | assert(pcmp); |
699 | 698 | |
702 | 701 | return -EINVAL; |
703 | 702 | } |
704 | 703 | |
705 | dshare = calloc(1, sizeof(snd_pcm_direct_t)); | |
706 | if (!dshare) { | |
707 | ret = -ENOMEM; | |
708 | goto _err_nosem; | |
709 | } | |
710 | ||
711 | ret = snd_pcm_direct_parse_bindings(dshare, params, opts->bindings); | |
704 | ret = _snd_pcm_direct_new(&pcm, &dshare, SND_PCM_TYPE_DSHARE, name, opts, params, stream, mode); | |
712 | 705 | if (ret < 0) |
713 | goto _err_nosem; | |
714 | ||
715 | dshare->ipc_key = opts->ipc_key; | |
716 | dshare->ipc_perm = opts->ipc_perm; | |
717 | dshare->ipc_gid = opts->ipc_gid; | |
718 | dshare->tstamp_type = opts->tstamp_type; | |
719 | dshare->semid = -1; | |
720 | dshare->shmid = -1; | |
721 | ||
722 | ret = snd_pcm_new(&pcm, dshare->type = SND_PCM_TYPE_DSHARE, name, stream, mode); | |
723 | if (ret < 0) | |
724 | goto _err_nosem; | |
725 | ||
726 | while (1) { | |
727 | ret = snd_pcm_direct_semaphore_create_or_connect(dshare); | |
728 | if (ret < 0) { | |
729 | SNDERR("unable to create IPC semaphore"); | |
730 | goto _err_nosem; | |
731 | } | |
732 | ||
733 | ret = snd_pcm_direct_semaphore_down(dshare, DIRECT_IPC_SEM_CLIENT); | |
734 | if (ret < 0) { | |
735 | snd_pcm_direct_semaphore_discard(dshare); | |
736 | if (--fail_sem_loop <= 0) | |
737 | goto _err_nosem; | |
738 | continue; | |
739 | } | |
740 | break; | |
741 | } | |
742 | ||
743 | first_instance = ret = snd_pcm_direct_shm_create_or_connect(dshare); | |
744 | if (ret < 0) { | |
745 | SNDERR("unable to create IPC shm instance"); | |
746 | goto _err; | |
747 | } | |
706 | return ret; | |
707 | first_instance = ret; | |
748 | 708 | |
749 | 709 | if (!dshare->bindings) { |
750 | 710 | pcm->ops = &snd_pcm_dshare_dummy_ops; |
874 | 834 | return 0; |
875 | 835 | |
876 | 836 | _err: |
877 | if (dshare->shmptr) | |
837 | if (dshare->shmptr != (void *) -1) | |
878 | 838 | dshare->shmptr->u.dshare.chn_mask &= ~dshare->u.dshare.chn_mask; |
879 | 839 | if (dshare->timer) |
880 | 840 | snd_timer_close(dshare->timer); |
890 | 850 | } else |
891 | 851 | snd_pcm_direct_semaphore_up(dshare, DIRECT_IPC_SEM_CLIENT); |
892 | 852 | _err_nosem: |
893 | if (dshare) { | |
894 | free(dshare->bindings); | |
895 | free(dshare); | |
896 | } | |
897 | if (pcm) | |
898 | snd_pcm_free(pcm); | |
853 | free(dshare->bindings); | |
854 | free(dshare); | |
855 | snd_pcm_free(pcm); | |
899 | 856 | return ret; |
900 | 857 | } |
901 | 858 |
192 | 192 | snd_pcm_status(dsnoop->spcm, status); |
193 | 193 | state = snd_pcm_state(dsnoop->spcm); |
194 | 194 | status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state; |
195 | status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */ | |
195 | 196 | status->trigger_tstamp = dsnoop->trigger_tstamp; |
196 | 197 | status->avail = snd_pcm_mmap_capture_avail(pcm); |
197 | 198 | status->avail_max = status->avail > dsnoop->avail_max ? status->avail : dsnoop->avail_max; |
562 | 563 | snd_config_t *root, snd_config_t *sconf, |
563 | 564 | snd_pcm_stream_t stream, int mode) |
564 | 565 | { |
565 | snd_pcm_t *pcm = NULL, *spcm = NULL; | |
566 | snd_pcm_direct_t *dsnoop = NULL; | |
567 | int ret, first_instance, fail_sem_loop = 10; | |
566 | snd_pcm_t *pcm, *spcm = NULL; | |
567 | snd_pcm_direct_t *dsnoop; | |
568 | int ret, first_instance; | |
568 | 569 | |
569 | 570 | assert(pcmp); |
570 | 571 | |
573 | 574 | return -EINVAL; |
574 | 575 | } |
575 | 576 | |
576 | dsnoop = calloc(1, sizeof(snd_pcm_direct_t)); | |
577 | if (!dsnoop) { | |
578 | ret = -ENOMEM; | |
579 | goto _err_nosem; | |
580 | } | |
581 | ||
582 | ret = snd_pcm_direct_parse_bindings(dsnoop, params, opts->bindings); | |
577 | ret = _snd_pcm_direct_new(&pcm, &dsnoop, SND_PCM_TYPE_DSNOOP, name, opts, params, stream, mode); | |
583 | 578 | if (ret < 0) |
584 | goto _err_nosem; | |
585 | ||
586 | dsnoop->ipc_key = opts->ipc_key; | |
587 | dsnoop->ipc_perm = opts->ipc_perm; | |
588 | dsnoop->ipc_gid = opts->ipc_gid; | |
589 | dsnoop->tstamp_type = opts->tstamp_type; | |
590 | dsnoop->semid = -1; | |
591 | dsnoop->shmid = -1; | |
592 | ||
593 | ret = snd_pcm_new(&pcm, dsnoop->type = SND_PCM_TYPE_DSNOOP, name, stream, mode); | |
594 | if (ret < 0) | |
595 | goto _err_nosem; | |
596 | ||
597 | while (1) { | |
598 | ret = snd_pcm_direct_semaphore_create_or_connect(dsnoop); | |
599 | if (ret < 0) { | |
600 | SNDERR("unable to create IPC semaphore"); | |
601 | goto _err_nosem; | |
602 | } | |
603 | ||
604 | ret = snd_pcm_direct_semaphore_down(dsnoop, DIRECT_IPC_SEM_CLIENT); | |
605 | if (ret < 0) { | |
606 | snd_pcm_direct_semaphore_discard(dsnoop); | |
607 | if (--fail_sem_loop <= 0) | |
608 | goto _err_nosem; | |
609 | continue; | |
610 | } | |
611 | break; | |
612 | } | |
613 | ||
614 | first_instance = ret = snd_pcm_direct_shm_create_or_connect(dsnoop); | |
615 | if (ret < 0) { | |
616 | SNDERR("unable to create IPC shm instance"); | |
617 | goto _err; | |
618 | } | |
619 | ||
579 | return ret; | |
580 | first_instance = ret; | |
581 | ||
620 | 582 | pcm->ops = &snd_pcm_dsnoop_ops; |
621 | 583 | pcm->fast_ops = &snd_pcm_dsnoop_fast_ops; |
622 | 584 | pcm->private_data = dsnoop; |
745 | 707 | snd_pcm_direct_semaphore_up(dsnoop, DIRECT_IPC_SEM_CLIENT); |
746 | 708 | |
747 | 709 | _err_nosem: |
748 | if (dsnoop) { | |
749 | free(dsnoop->bindings); | |
750 | free(dsnoop); | |
751 | } | |
752 | if (pcm) | |
753 | snd_pcm_free(pcm); | |
710 | free(dsnoop->bindings); | |
711 | free(dsnoop); | |
712 | snd_pcm_free(pcm); | |
754 | 713 | return ret; |
755 | 714 | } |
756 | 715 |
0 | 0 | /** |
1 | 1 | * \file pcm/pcm_empty.c |
2 | 2 | * \ingroup PCM_Plugins |
3 | * \brief PCM Null Plugin Interface | |
3 | * \brief PCM Empty Plugin Interface | |
4 | 4 | * \author Jaroslav Kysela <perex@perex.cz> |
5 | 5 | * \date 2006 |
6 | 6 | */ |
7 | 7 | /* |
8 | * PCM - Null plugin | |
8 | * PCM - Empty plugin | |
9 | 9 | * Copyright (c) 2006 by Jaroslav Kysela <perex@perex.cz> |
10 | 10 | * |
11 | 11 | * |
35 | 35 | |
36 | 36 | /*! \page pcm_plugins |
37 | 37 | |
38 | \section pcm_plugins_null Plugin: Null | |
38 | \section pcm_plugins_empty Plugin: Empty | |
39 | 39 | |
40 | This plugin discards contents of a PCM stream or creates a stream with zero | |
41 | samples. | |
42 | ||
43 | Note: This implementation uses devices /dev/null (playback, must be writable) | |
44 | and /dev/full (capture, must be readable). | |
40 | This plugin just redirects the PCM stream to another plugin. | |
45 | 41 | |
46 | 42 | \code |
47 | 43 | pcm.name { |
48 | type null # Null PCM | |
44 | type empty # Null PCM | |
45 | slave STR # Slave name | |
46 | # or | |
47 | slave { # Slave definition | |
48 | pcm STR # Slave PCM name | |
49 | # or | |
50 | pcm { } # Slave PCM definition | |
51 | [format STR] # Slave format | |
52 | [channels INT] # Slave channels | |
53 | } | |
49 | 54 | } |
50 | 55 | \endcode |
51 | 56 | |
52 | \subsection pcm_plugins_null_funcref Function reference | |
57 | \subsection pcm_plugins_empty_funcref Function reference | |
53 | 58 | |
54 | 59 | <UL> |
55 | 60 | <LI>_snd_pcm_empty_open() |
599 | 599 | static snd_pcm_state_t snd_pcm_hw_state(snd_pcm_t *pcm) |
600 | 600 | { |
601 | 601 | snd_pcm_hw_t *hw = pcm->private_data; |
602 | int err = query_status_data(hw); | |
603 | if (err < 0) | |
604 | return err; | |
602 | /* the -ENODEV may come from the snd_disconnect_ioctl() or | |
603 | snd_power_wait() in kernel */ | |
604 | if (query_status_data(hw) == -ENODEV) | |
605 | return SND_PCM_STATE_DISCONNECTED; | |
605 | 606 | return (snd_pcm_state_t) hw->mmap_status->state; |
606 | 607 | } |
607 | 608 | |
1815 | 1816 | if (snd_pcm_conf_generic_id(id)) |
1816 | 1817 | continue; |
1817 | 1818 | if (strcmp(id, "card") == 0) { |
1818 | err = snd_config_get_integer(n, &card); | |
1819 | if (err < 0) { | |
1820 | err = snd_config_get_string(n, &str); | |
1821 | if (err < 0) { | |
1822 | SNDERR("Invalid type for %s", id); | |
1823 | err = -EINVAL; | |
1824 | goto fail; | |
1825 | } | |
1826 | card = snd_card_get_index(str); | |
1827 | if (card < 0) { | |
1828 | SNDERR("Invalid value for %s", id); | |
1829 | err = card; | |
1830 | goto fail; | |
1831 | } | |
1832 | } | |
1819 | err = snd_config_get_card(n); | |
1820 | if (err < 0) | |
1821 | goto fail; | |
1822 | card = err; | |
1833 | 1823 | continue; |
1834 | 1824 | } |
1835 | 1825 | if (strcmp(id, "device") == 0) { |
106 | 106 | return snd_pcm_channel_info_shm(pcm, info, -1); |
107 | 107 | } |
108 | 108 | |
109 | static int snd_pcm_ioplug_status(snd_pcm_t *pcm, snd_pcm_status_t * status) | |
110 | { | |
111 | ioplug_priv_t *io = pcm->private_data; | |
112 | ||
113 | memset(status, 0, sizeof(*status)); | |
114 | snd_pcm_ioplug_hw_ptr_update(pcm); | |
115 | status->state = io->data->state; | |
116 | status->trigger_tstamp = io->trigger_tstamp; | |
117 | status->avail = snd_pcm_mmap_avail(pcm); | |
118 | status->avail_max = io->avail_max; | |
119 | return 0; | |
120 | } | |
121 | ||
122 | static snd_pcm_state_t snd_pcm_ioplug_state(snd_pcm_t *pcm) | |
123 | { | |
124 | ioplug_priv_t *io = pcm->private_data; | |
125 | return io->data->state; | |
126 | } | |
127 | ||
128 | static int snd_pcm_ioplug_hwsync(snd_pcm_t *pcm) | |
129 | { | |
130 | snd_pcm_ioplug_hw_ptr_update(pcm); | |
131 | return 0; | |
132 | } | |
133 | ||
134 | 109 | static int snd_pcm_ioplug_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) |
135 | 110 | { |
136 | 111 | ioplug_priv_t *io = pcm->private_data; |
140 | 115 | return io->data->callback->delay(io->data, delayp); |
141 | 116 | else { |
142 | 117 | snd_pcm_ioplug_hw_ptr_update(pcm); |
143 | *delayp = snd_pcm_mmap_hw_avail(pcm); | |
144 | } | |
118 | *delayp = snd_pcm_mmap_delay(pcm); | |
119 | } | |
120 | return 0; | |
121 | } | |
122 | ||
123 | static int snd_pcm_ioplug_status(snd_pcm_t *pcm, snd_pcm_status_t * status) | |
124 | { | |
125 | ioplug_priv_t *io = pcm->private_data; | |
126 | snd_pcm_sframes_t sd; | |
127 | ||
128 | memset(status, 0, sizeof(*status)); | |
129 | snd_pcm_ioplug_hw_ptr_update(pcm); | |
130 | status->state = io->data->state; | |
131 | status->trigger_tstamp = io->trigger_tstamp; | |
132 | gettimestamp(&status->tstamp, pcm->tstamp_type); | |
133 | status->avail = snd_pcm_mmap_avail(pcm); | |
134 | status->avail_max = io->avail_max; | |
135 | status->appl_ptr = *pcm->appl.ptr; | |
136 | status->hw_ptr = *pcm->hw.ptr; | |
137 | if (snd_pcm_ioplug_delay(pcm, &sd) < 0) | |
138 | sd = snd_pcm_mmap_delay(pcm); | |
139 | status->delay = sd; | |
140 | return 0; | |
141 | } | |
142 | ||
143 | static snd_pcm_state_t snd_pcm_ioplug_state(snd_pcm_t *pcm) | |
144 | { | |
145 | ioplug_priv_t *io = pcm->private_data; | |
146 | return io->data->state; | |
147 | } | |
148 | ||
149 | static int snd_pcm_ioplug_hwsync(snd_pcm_t *pcm) | |
150 | { | |
151 | snd_pcm_ioplug_hw_ptr_update(pcm); | |
145 | 152 | return 0; |
146 | 153 | } |
147 | 154 | |
689 | 696 | } |
690 | 697 | } |
691 | 698 | |
699 | static int snd_pcm_ioplug_mmap_begin_capture(snd_pcm_t *pcm, | |
700 | const snd_pcm_channel_area_t **areas, | |
701 | snd_pcm_uframes_t *offset, | |
702 | snd_pcm_uframes_t *frames) | |
703 | { | |
704 | ioplug_priv_t *io = pcm->private_data; | |
705 | int err; | |
706 | ||
707 | err = __snd_pcm_mmap_begin_generic(pcm, areas, offset, frames); | |
708 | if (err < 0) | |
709 | return err; | |
710 | ||
711 | if (io->data->callback->transfer && | |
712 | pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED && | |
713 | pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) { | |
714 | snd_pcm_sframes_t result; | |
715 | result = io->data->callback->transfer(io->data, *areas, *offset, *frames); | |
716 | if (result < 0) | |
717 | return result; | |
718 | } | |
719 | ||
720 | return err; | |
721 | } | |
722 | ||
723 | static int snd_pcm_ioplug_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, | |
724 | snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames) | |
725 | { | |
726 | if (pcm->stream == SND_PCM_STREAM_PLAYBACK) | |
727 | return __snd_pcm_mmap_begin_generic(pcm, areas, offset, frames); | |
728 | return snd_pcm_ioplug_mmap_begin_capture(pcm, areas, offset, frames); | |
729 | } | |
730 | ||
692 | 731 | static snd_pcm_sframes_t snd_pcm_ioplug_mmap_commit(snd_pcm_t *pcm, |
693 | 732 | snd_pcm_uframes_t offset, |
694 | 733 | snd_pcm_uframes_t size) |
699 | 738 | const snd_pcm_channel_area_t *areas; |
700 | 739 | snd_pcm_uframes_t ofs, frames = size; |
701 | 740 | |
702 | __snd_pcm_mmap_begin(pcm, &areas, &ofs, &frames); | |
741 | __snd_pcm_mmap_begin_generic(pcm, &areas, &ofs, &frames); | |
703 | 742 | if (ofs != offset) |
704 | 743 | return -EIO; |
705 | 744 | return ioplug_priv_transfer_areas(pcm, areas, offset, frames); |
719 | 758 | return -EPIPE; |
720 | 759 | |
721 | 760 | avail = snd_pcm_mmap_avail(pcm); |
722 | if (pcm->stream == SND_PCM_STREAM_CAPTURE && | |
723 | pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED && | |
724 | pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) { | |
725 | if (io->data->callback->transfer) { | |
726 | const snd_pcm_channel_area_t *areas; | |
727 | snd_pcm_uframes_t offset, size = UINT_MAX; | |
728 | snd_pcm_sframes_t result; | |
729 | ||
730 | __snd_pcm_mmap_begin(pcm, &areas, &offset, &size); | |
731 | result = io->data->callback->transfer(io->data, areas, offset, size); | |
732 | if (result < 0) | |
733 | return result; | |
734 | ||
735 | /* If the available data doesn't fit in the | |
736 | contiguous area at the end of the mmap we | |
737 | must transfer the remaining data to the | |
738 | beginning of the mmap. */ | |
739 | if (size < avail) { | |
740 | result = io->data->callback->transfer(io->data, areas, | |
741 | 0, avail - size); | |
742 | if (result < 0) | |
743 | return result; | |
744 | } | |
745 | } | |
746 | } | |
747 | 761 | if (avail > io->avail_max) |
748 | 762 | io->avail_max = avail; |
749 | 763 | return (snd_pcm_sframes_t)avail; |
939 | 953 | .poll_descriptors_count = snd_pcm_ioplug_poll_descriptors_count, |
940 | 954 | .poll_descriptors = snd_pcm_ioplug_poll_descriptors, |
941 | 955 | .poll_revents = snd_pcm_ioplug_poll_revents, |
956 | .mmap_begin = snd_pcm_ioplug_mmap_begin, | |
942 | 957 | }; |
943 | 958 | |
944 | 959 | #endif /* !DOC_HIDDEN */ |
419 | 419 | #define _snd_pcm_async_descriptor _snd_pcm_poll_descriptor /* FIXME */ |
420 | 420 | |
421 | 421 | /* locked versions */ |
422 | int __snd_pcm_mmap_begin_generic(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, | |
423 | snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames); | |
422 | 424 | int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, |
423 | 425 | snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames); |
424 | 426 | snd_pcm_sframes_t __snd_pcm_mmap_commit(snd_pcm_t *pcm, |
443 | 445 | static inline snd_pcm_state_t __snd_pcm_state(snd_pcm_t *pcm) |
444 | 446 | { |
445 | 447 | if (!pcm->fast_ops->state) |
446 | return -ENOSYS; | |
448 | return SND_PCM_STATE_OPEN; | |
447 | 449 | return pcm->fast_ops->state(pcm->fast_op_arg); |
448 | 450 | } |
449 | 451 |
752 | 752 | return linear_formats[width][!!unsignd][!!big_endian]; |
753 | 753 | } |
754 | 754 | } |
755 | ||
756 | /** | |
757 | * \brief Parse control element id from the config | |
758 | * \param conf the config tree to parse | |
759 | * \param ctl_id the pointer to store the resultant control element id | |
760 | * \param cardp the pointer to store the card index | |
761 | * \param cchannelsp the pointer to store the number of channels (optional) | |
762 | * \param hwctlp the pointer to store the h/w control flag (optional) | |
763 | * \return 0 if successful, or a negative error code | |
764 | * | |
765 | * This function parses the given config tree to retrieve the control element id | |
766 | * and the card index. It's used by softvol. External PCM plugins can use this | |
767 | * function for creating or assigining their controls. | |
768 | * | |
769 | * cchannelsp and hwctlp arguments are optional. Set NULL if not necessary. | |
770 | */ | |
771 | int snd_pcm_parse_control_id(snd_config_t *conf, snd_ctl_elem_id_t *ctl_id, int *cardp, | |
772 | int *cchannelsp, int *hwctlp) | |
773 | { | |
774 | snd_config_iterator_t i, next; | |
775 | int iface = SND_CTL_ELEM_IFACE_MIXER; | |
776 | const char *name = NULL; | |
777 | long index = 0; | |
778 | long device = -1; | |
779 | long subdevice = -1; | |
780 | int err; | |
781 | ||
782 | assert(ctl_id && cardp); | |
783 | ||
784 | *cardp = -1; | |
785 | if (cchannelsp) | |
786 | *cchannelsp = 2; | |
787 | snd_config_for_each(i, next, conf) { | |
788 | snd_config_t *n = snd_config_iterator_entry(i); | |
789 | const char *id; | |
790 | if (snd_config_get_id(n, &id) < 0) | |
791 | continue; | |
792 | if (strcmp(id, "comment") == 0) | |
793 | continue; | |
794 | if (strcmp(id, "card") == 0) { | |
795 | const char *str; | |
796 | long v; | |
797 | if ((err = snd_config_get_integer(n, &v)) < 0) { | |
798 | if ((err = snd_config_get_string(n, &str)) < 0) { | |
799 | SNDERR("Invalid field %s", id); | |
800 | goto _err; | |
801 | } | |
802 | *cardp = snd_card_get_index(str); | |
803 | if (*cardp < 0) { | |
804 | SNDERR("Cannot get index for %s", str); | |
805 | err = *cardp; | |
806 | goto _err; | |
807 | } | |
808 | } else | |
809 | *cardp = v; | |
810 | continue; | |
811 | } | |
812 | if (strcmp(id, "iface") == 0 || strcmp(id, "interface") == 0) { | |
813 | const char *ptr; | |
814 | if ((err = snd_config_get_string(n, &ptr)) < 0) { | |
815 | SNDERR("field %s is not a string", id); | |
816 | goto _err; | |
817 | } | |
818 | if ((err = snd_config_get_ctl_iface_ascii(ptr)) < 0) { | |
819 | SNDERR("Invalid value for '%s'", id); | |
820 | goto _err; | |
821 | } | |
822 | iface = err; | |
823 | continue; | |
824 | } | |
825 | if (strcmp(id, "name") == 0) { | |
826 | if ((err = snd_config_get_string(n, &name)) < 0) { | |
827 | SNDERR("field %s is not a string", id); | |
828 | goto _err; | |
829 | } | |
830 | continue; | |
831 | } | |
832 | if (strcmp(id, "index") == 0) { | |
833 | if ((err = snd_config_get_integer(n, &index)) < 0) { | |
834 | SNDERR("field %s is not an integer", id); | |
835 | goto _err; | |
836 | } | |
837 | continue; | |
838 | } | |
839 | if (strcmp(id, "device") == 0) { | |
840 | if ((err = snd_config_get_integer(n, &device)) < 0) { | |
841 | SNDERR("field %s is not an integer", id); | |
842 | goto _err; | |
843 | } | |
844 | continue; | |
845 | } | |
846 | if (strcmp(id, "subdevice") == 0) { | |
847 | if ((err = snd_config_get_integer(n, &subdevice)) < 0) { | |
848 | SNDERR("field %s is not an integer", id); | |
849 | goto _err; | |
850 | } | |
851 | continue; | |
852 | } | |
853 | if (cchannelsp && strcmp(id, "count") == 0) { | |
854 | long v; | |
855 | if ((err = snd_config_get_integer(n, &v)) < 0) { | |
856 | SNDERR("field %s is not an integer", id); | |
857 | goto _err; | |
858 | } | |
859 | if (v < 1 || v > 2) { | |
860 | SNDERR("Invalid count %ld", v); | |
861 | goto _err; | |
862 | } | |
863 | *cchannelsp = v; | |
864 | continue; | |
865 | } | |
866 | if (hwctlp && strcmp(id, "hwctl") == 0) { | |
867 | if ((err = snd_config_get_bool(n)) < 0) { | |
868 | SNDERR("The field %s must be a boolean type", id); | |
869 | return err; | |
870 | } | |
871 | *hwctlp = err; | |
872 | continue; | |
873 | } | |
874 | SNDERR("Unknown field %s", id); | |
875 | return -EINVAL; | |
876 | } | |
877 | if (name == NULL) { | |
878 | SNDERR("Missing control name"); | |
879 | err = -EINVAL; | |
880 | goto _err; | |
881 | } | |
882 | if (device < 0) | |
883 | device = 0; | |
884 | if (subdevice < 0) | |
885 | subdevice = 0; | |
886 | ||
887 | snd_ctl_elem_id_set_interface(ctl_id, iface); | |
888 | snd_ctl_elem_id_set_name(ctl_id, name); | |
889 | snd_ctl_elem_id_set_index(ctl_id, index); | |
890 | snd_ctl_elem_id_set_device(ctl_id, device); | |
891 | snd_ctl_elem_id_set_subdevice(ctl_id, subdevice); | |
892 | ||
893 | return 0; | |
894 | ||
895 | _err: | |
896 | return err; | |
897 | } |
182 | 182 | * \brief Read interleaved frames from a PCM using direct buffer (mmap) |
183 | 183 | * \param pcm PCM handle |
184 | 184 | * \param buffer frames containing buffer |
185 | * \param size frames to be written | |
185 | * \param size frames to be read | |
186 | 186 | * \return a positive number of frames actually read otherwise a |
187 | 187 | * negative error code |
188 | 188 | * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING) |
1322 | 1322 | err = -ENOMEM; |
1323 | 1323 | goto _free; |
1324 | 1324 | } |
1325 | idx = 0; | |
1326 | 1325 | for (idx = 0; idx < channels_count; ++idx) |
1327 | 1326 | channels_sidx[idx] = -1; |
1328 | 1327 | idx = 0; |
95 | 95 | memset(status, 0, sizeof(*status)); |
96 | 96 | status->state = null->state; |
97 | 97 | status->trigger_tstamp = null->trigger_tstamp; |
98 | status->appl_ptr = *pcm->appl.ptr; | |
99 | status->hw_ptr = *pcm->hw.ptr; | |
98 | 100 | gettimestamp(&status->tstamp, pcm->tstamp_type); |
99 | 101 | status->avail = snd_pcm_null_avail_update(pcm); |
100 | 102 | status->avail_max = pcm->buffer_size; |
141 | 141 | int err = snd_pcm_delay(plugin->gen.slave, &sd); |
142 | 142 | if (err < 0) |
143 | 143 | return err; |
144 | if (pcm->stream == SND_PCM_STREAM_CAPTURE && | |
145 | pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED && | |
146 | pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) { | |
147 | sd += snd_pcm_mmap_capture_avail(pcm); | |
148 | } | |
149 | ||
150 | 144 | *delayp = sd; |
145 | return 0; | |
146 | } | |
147 | ||
148 | static int snd_pcm_plugin_call_init_cb(snd_pcm_t *pcm, snd_pcm_plugin_t *plugin) | |
149 | { | |
150 | snd_pcm_t *slave = plugin->gen.slave; | |
151 | int err; | |
152 | ||
153 | assert(pcm->boundary == slave->boundary); | |
154 | *pcm->hw.ptr = *slave->hw.ptr; | |
155 | *pcm->appl.ptr = *slave->appl.ptr; | |
156 | if (plugin->init) { | |
157 | err = plugin->init(pcm); | |
158 | if (err < 0) | |
159 | return err; | |
160 | } | |
151 | 161 | return 0; |
152 | 162 | } |
153 | 163 | |
158 | 168 | err = snd_pcm_prepare(plugin->gen.slave); |
159 | 169 | if (err < 0) |
160 | 170 | return err; |
161 | *pcm->hw.ptr = 0; | |
162 | *pcm->appl.ptr = 0; | |
163 | if (plugin->init) { | |
164 | err = plugin->init(pcm); | |
165 | if (err < 0) | |
166 | return err; | |
167 | } | |
168 | return 0; | |
171 | return snd_pcm_plugin_call_init_cb(pcm, plugin); | |
169 | 172 | } |
170 | 173 | |
171 | 174 | static int snd_pcm_plugin_reset(snd_pcm_t *pcm) |
175 | 178 | err = snd_pcm_reset(plugin->gen.slave); |
176 | 179 | if (err < 0) |
177 | 180 | return err; |
178 | *pcm->hw.ptr = 0; | |
179 | *pcm->appl.ptr = 0; | |
180 | if (plugin->init) { | |
181 | err = plugin->init(pcm); | |
182 | if (err < 0) | |
183 | return err; | |
184 | } | |
185 | return 0; | |
181 | return snd_pcm_plugin_call_init_cb(pcm, plugin); | |
186 | 182 | } |
187 | 183 | |
188 | 184 | static snd_pcm_sframes_t snd_pcm_plugin_rewindable(snd_pcm_t *pcm) |
459 | 455 | return xfer > 0 ? xfer : err; |
460 | 456 | } |
461 | 457 | |
462 | static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm) | |
458 | static snd_pcm_sframes_t | |
459 | snd_pcm_plugin_sync_hw_ptr_capture(snd_pcm_t *pcm, | |
460 | snd_pcm_sframes_t slave_size) | |
463 | 461 | { |
464 | 462 | snd_pcm_plugin_t *plugin = pcm->private_data; |
465 | 463 | snd_pcm_t *slave = plugin->gen.slave; |
466 | snd_pcm_sframes_t slave_size; | |
464 | const snd_pcm_channel_area_t *areas; | |
465 | snd_pcm_uframes_t xfer, hw_offset, size; | |
467 | 466 | int err; |
468 | 467 | |
469 | slave_size = snd_pcm_avail_update(slave); | |
468 | xfer = snd_pcm_mmap_capture_avail(pcm); | |
469 | size = pcm->buffer_size - xfer; | |
470 | areas = snd_pcm_mmap_areas(pcm); | |
471 | hw_offset = snd_pcm_mmap_hw_offset(pcm); | |
472 | while (size > 0 && slave_size > 0) { | |
473 | snd_pcm_uframes_t frames = size; | |
474 | snd_pcm_uframes_t cont = pcm->buffer_size - hw_offset; | |
475 | const snd_pcm_channel_area_t *slave_areas; | |
476 | snd_pcm_uframes_t slave_offset; | |
477 | snd_pcm_uframes_t slave_frames = ULONG_MAX; | |
478 | snd_pcm_sframes_t result; | |
479 | /* As mentioned in the ALSA API (see pcm/pcm.c:942): | |
480 | * The function #snd_pcm_avail_update() | |
481 | * have to be called before any mmap begin+commit operation. | |
482 | * Otherwise the snd_pcm_areas_copy will not called a second time. | |
483 | * But this is needed, if the ring buffer wrap is reached and | |
484 | * there is more data available. | |
485 | */ | |
486 | slave_size = snd_pcm_avail_update(slave); | |
487 | result = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames); | |
488 | if (result < 0) { | |
489 | err = result; | |
490 | goto error; | |
491 | } | |
492 | if (frames > cont) | |
493 | frames = cont; | |
494 | frames = (plugin->read)(pcm, areas, hw_offset, frames, | |
495 | slave_areas, slave_offset, &slave_frames); | |
496 | result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames); | |
497 | if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) { | |
498 | snd_pcm_sframes_t res; | |
499 | res = plugin->undo_read(slave, areas, hw_offset, frames, slave_frames - result); | |
500 | if (res < 0) { | |
501 | err = res; | |
502 | goto error; | |
503 | } | |
504 | frames -= res; | |
505 | } | |
506 | if (result <= 0) { | |
507 | err = result; | |
508 | goto error; | |
509 | } | |
510 | snd_pcm_mmap_hw_forward(pcm, frames); | |
511 | if (frames == cont) | |
512 | hw_offset = 0; | |
513 | else | |
514 | hw_offset += frames; | |
515 | size -= frames; | |
516 | slave_size -= slave_frames; | |
517 | xfer += frames; | |
518 | } | |
519 | return (snd_pcm_sframes_t)xfer; | |
520 | error: | |
521 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; | |
522 | } | |
523 | ||
524 | static snd_pcm_sframes_t snd_pcm_plugin_sync_hw_ptr(snd_pcm_t *pcm, | |
525 | snd_pcm_uframes_t slave_hw_ptr, | |
526 | snd_pcm_sframes_t slave_size) | |
527 | { | |
470 | 528 | if (pcm->stream == SND_PCM_STREAM_CAPTURE && |
471 | 529 | pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED && |
472 | 530 | pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) |
473 | goto _capture; | |
474 | *pcm->hw.ptr = *slave->hw.ptr; | |
531 | return snd_pcm_plugin_sync_hw_ptr_capture(pcm, slave_size); | |
532 | *pcm->hw.ptr = slave_hw_ptr; | |
475 | 533 | return slave_size; |
476 | _capture: | |
477 | { | |
478 | const snd_pcm_channel_area_t *areas; | |
479 | snd_pcm_uframes_t xfer, hw_offset, size; | |
480 | ||
481 | xfer = snd_pcm_mmap_capture_avail(pcm); | |
482 | size = pcm->buffer_size - xfer; | |
483 | areas = snd_pcm_mmap_areas(pcm); | |
484 | hw_offset = snd_pcm_mmap_hw_offset(pcm); | |
485 | while (size > 0 && slave_size > 0) { | |
486 | snd_pcm_uframes_t frames = size; | |
487 | snd_pcm_uframes_t cont = pcm->buffer_size - hw_offset; | |
488 | const snd_pcm_channel_area_t *slave_areas; | |
489 | snd_pcm_uframes_t slave_offset; | |
490 | snd_pcm_uframes_t slave_frames = ULONG_MAX; | |
491 | snd_pcm_sframes_t result; | |
492 | /* As mentioned in the ALSA API (see pcm/pcm.c:942): | |
493 | * The function #snd_pcm_avail_update() | |
494 | * have to be called before any mmap begin+commit operation. | |
495 | * Otherwise the snd_pcm_areas_copy will not called a second time. | |
496 | * But this is needed, if the ring buffer wrap is reached and | |
497 | * there is more data available. | |
498 | */ | |
499 | slave_size = snd_pcm_avail_update(slave); | |
500 | result = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames); | |
501 | if (result < 0) { | |
502 | err = result; | |
503 | goto error; | |
504 | } | |
505 | if (frames > cont) | |
506 | frames = cont; | |
507 | frames = (plugin->read)(pcm, areas, hw_offset, frames, | |
508 | slave_areas, slave_offset, &slave_frames); | |
509 | result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames); | |
510 | if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) { | |
511 | snd_pcm_sframes_t res; | |
512 | ||
513 | res = plugin->undo_read(slave, areas, hw_offset, frames, slave_frames - result); | |
514 | if (res < 0) { | |
515 | err = res; | |
516 | goto error; | |
517 | } | |
518 | frames -= res; | |
519 | } | |
520 | if (result <= 0) { | |
521 | err = result; | |
522 | goto error; | |
523 | } | |
524 | snd_pcm_mmap_hw_forward(pcm, frames); | |
525 | if (frames == cont) | |
526 | hw_offset = 0; | |
527 | else | |
528 | hw_offset += frames; | |
529 | size -= frames; | |
530 | slave_size -= slave_frames; | |
531 | xfer += frames; | |
532 | } | |
533 | return (snd_pcm_sframes_t)xfer; | |
534 | ||
535 | error: | |
536 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; | |
537 | } | |
534 | } | |
535 | ||
536 | static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm) | |
537 | { | |
538 | snd_pcm_plugin_t *plugin = pcm->private_data; | |
539 | snd_pcm_t *slave = plugin->gen.slave; | |
540 | snd_pcm_sframes_t slave_size; | |
541 | ||
542 | slave_size = snd_pcm_avail_update(slave); | |
543 | return snd_pcm_plugin_sync_hw_ptr(pcm, *slave->hw.ptr, slave_size); | |
538 | 544 | } |
539 | 545 | |
540 | 546 | static int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status) |
541 | 547 | { |
542 | 548 | snd_pcm_plugin_t *plugin = pcm->private_data; |
543 | snd_pcm_sframes_t err, avail; | |
544 | ||
545 | /* sync with the latest hw and appl ptrs */ | |
546 | avail = snd_pcm_plugin_avail_update(pcm); | |
547 | if (avail < 0) | |
548 | return avail; | |
549 | snd_pcm_sframes_t err, diff; | |
549 | 550 | |
550 | 551 | err = snd_pcm_status(plugin->gen.slave, status); |
551 | 552 | if (err < 0) |
552 | 553 | return err; |
553 | status->appl_ptr = *pcm->appl.ptr; | |
554 | status->hw_ptr = *pcm->hw.ptr; | |
555 | status->avail = avail; | |
556 | status->delay = snd_pcm_mmap_delay(pcm); | |
554 | snd_pcm_plugin_sync_hw_ptr(pcm, status->hw_ptr, status->avail); | |
555 | /* | |
556 | * For capture stream, the situation is more complicated, because | |
557 | * snd_pcm_plugin_avail_update() commits the data to the slave pcm. | |
558 | * It means that the slave appl_ptr is updated. Calculate diff and | |
559 | * update the delay and avail. | |
560 | * | |
561 | * This resolves the data inconsistency for immediate calls: | |
562 | * snd_pcm_avail_update() | |
563 | * snd_pcm_status() | |
564 | */ | |
565 | if (pcm->stream == SND_PCM_STREAM_CAPTURE) { | |
566 | diff = pcm_frame_diff(status->appl_ptr, *pcm->appl.ptr, pcm->boundary); | |
567 | status->appl_ptr = *pcm->appl.ptr; | |
568 | status->avail += diff; | |
569 | status->delay += diff; | |
570 | } else { | |
571 | assert(status->appl_ptr == *pcm->appl.ptr); | |
572 | } | |
557 | 573 | return 0; |
558 | 574 | } |
559 | 575 |
560 | 560 | |
561 | 561 | static inline void snd_pcm_rate_sync_hwptr0(snd_pcm_t *pcm, snd_pcm_uframes_t slave_hw_ptr) |
562 | 562 | { |
563 | snd_pcm_rate_t *rate = pcm->private_data; | |
564 | ||
565 | snd_pcm_sframes_t slave_hw_ptr_diff = slave_hw_ptr - rate->last_slave_hw_ptr; | |
563 | snd_pcm_rate_t *rate; | |
564 | snd_pcm_sframes_t slave_hw_ptr_diff; | |
566 | 565 | snd_pcm_sframes_t last_slave_hw_ptr_frac; |
567 | 566 | |
568 | 567 | if (pcm->stream != SND_PCM_STREAM_PLAYBACK) |
569 | 568 | return; |
570 | 569 | |
571 | if (slave_hw_ptr_diff < 0) | |
572 | slave_hw_ptr_diff += rate->gen.slave->boundary; /* slave boundary wraparound */ | |
573 | else if (slave_hw_ptr_diff == 0) | |
570 | rate = pcm->private_data; | |
571 | slave_hw_ptr_diff = pcm_frame_diff(slave_hw_ptr, rate->last_slave_hw_ptr, rate->gen.slave->boundary); | |
572 | if (slave_hw_ptr_diff == 0) | |
574 | 573 | return; |
575 | 574 | last_slave_hw_ptr_frac = rate->last_slave_hw_ptr % rate->gen.slave->period_size; |
576 | 575 | /* While handling fraction part fo slave period, rounded value will be |
611 | 610 | { |
612 | 611 | snd_pcm_rate_t *rate = pcm->private_data; |
613 | 612 | |
614 | if (rate->appl_ptr < rate->last_commit_ptr) { | |
615 | return rate->appl_ptr - rate->last_commit_ptr + pcm->boundary; | |
616 | } else { | |
617 | return rate->appl_ptr - rate->last_commit_ptr; | |
618 | } | |
613 | return pcm_frame_diff(rate->appl_ptr, rate->last_commit_ptr, pcm->boundary); | |
619 | 614 | } |
620 | 615 | |
621 | 616 | static int snd_pcm_rate_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) |
636 | 631 | + snd_pcm_rate_playback_internal_delay(pcm); |
637 | 632 | } else { |
638 | 633 | *delayp = rate->ops.output_frames(rate->obj, slave_delay) |
639 | + snd_pcm_mmap_capture_hw_avail(pcm); | |
634 | + snd_pcm_mmap_capture_delay(pcm); | |
640 | 635 | } |
641 | 636 | return 0; |
642 | 637 | } |
745 | 740 | if (result < 0) |
746 | 741 | return result; |
747 | 742 | __partial: |
748 | xfer = 0; | |
749 | 743 | cont = slave_frames; |
750 | 744 | if (cont > slave_size) |
751 | 745 | cont = slave_size; |
845 | 839 | if (result < 0) |
846 | 840 | return result; |
847 | 841 | __partial: |
848 | xfer = 0; | |
849 | 842 | cont = slave_frames; |
850 | 843 | if (cont > rate->gen.slave->period_size) |
851 | 844 | cont = rate->gen.slave->period_size; |
927 | 920 | if (slave_size < 0) |
928 | 921 | return slave_size; |
929 | 922 | |
930 | if (appl_ptr < rate->last_commit_ptr) | |
931 | xfer = appl_ptr - rate->last_commit_ptr + pcm->boundary; | |
932 | else | |
933 | xfer = appl_ptr - rate->last_commit_ptr; | |
923 | xfer = pcm_frame_diff(appl_ptr, rate->last_commit_ptr, pcm->boundary); | |
934 | 924 | while (xfer >= pcm->period_size && |
935 | 925 | (snd_pcm_uframes_t)slave_size >= rate->gen.slave->period_size) { |
936 | 926 | err = snd_pcm_rate_commit_next_period(pcm, rate->last_commit_ptr % pcm->buffer_size); |
965 | 955 | return size; |
966 | 956 | } |
967 | 957 | |
968 | static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm) | |
958 | static snd_pcm_sframes_t snd_pcm_rate_avail_update_capture(snd_pcm_t *pcm, | |
959 | snd_pcm_sframes_t slave_size) | |
969 | 960 | { |
970 | 961 | snd_pcm_rate_t *rate = pcm->private_data; |
971 | 962 | snd_pcm_t *slave = rate->gen.slave; |
972 | snd_pcm_sframes_t slave_size; | |
973 | ||
974 | slave_size = snd_pcm_avail_update(slave); | |
975 | if (slave_size < 0) | |
976 | return slave_size; | |
977 | ||
978 | if (pcm->stream == SND_PCM_STREAM_CAPTURE) | |
979 | goto _capture; | |
980 | snd_pcm_rate_sync_hwptr(pcm); | |
981 | snd_pcm_rate_sync_playback_area(pcm, rate->appl_ptr); | |
982 | return snd_pcm_mmap_avail(pcm); | |
983 | _capture: { | |
984 | 963 | snd_pcm_uframes_t xfer, hw_offset, size; |
985 | 964 | |
986 | 965 | xfer = snd_pcm_mmap_capture_avail(pcm); |
987 | 966 | size = pcm->buffer_size - xfer; |
988 | 967 | hw_offset = snd_pcm_mmap_hw_offset(pcm); |
989 | 968 | while (size >= pcm->period_size && |
990 | (snd_pcm_uframes_t)slave_size >= rate->gen.slave->period_size) { | |
969 | (snd_pcm_uframes_t)slave_size >= slave->period_size) { | |
991 | 970 | int err = snd_pcm_rate_grab_next_period(pcm, hw_offset); |
992 | 971 | if (err < 0) |
993 | 972 | return err; |
995 | 974 | return (snd_pcm_sframes_t)xfer; |
996 | 975 | xfer += pcm->period_size; |
997 | 976 | size -= pcm->period_size; |
998 | slave_size -= rate->gen.slave->period_size; | |
977 | slave_size -= slave->period_size; | |
999 | 978 | hw_offset += pcm->period_size; |
1000 | 979 | hw_offset %= pcm->buffer_size; |
1001 | 980 | snd_pcm_mmap_hw_forward(pcm, pcm->period_size); |
1002 | 981 | } |
1003 | 982 | return (snd_pcm_sframes_t)xfer; |
1004 | } | |
983 | } | |
984 | ||
985 | static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm) | |
986 | { | |
987 | snd_pcm_rate_t *rate = pcm->private_data; | |
988 | snd_pcm_sframes_t slave_size; | |
989 | ||
990 | slave_size = snd_pcm_avail_update(rate->gen.slave); | |
991 | if (slave_size < 0) | |
992 | return slave_size; | |
993 | ||
994 | if (pcm->stream == SND_PCM_STREAM_CAPTURE) | |
995 | return snd_pcm_rate_avail_update_capture(pcm, slave_size); | |
996 | ||
997 | snd_pcm_rate_sync_hwptr(pcm); | |
998 | snd_pcm_rate_sync_playback_area(pcm, rate->appl_ptr); | |
999 | return snd_pcm_mmap_avail(pcm); | |
1005 | 1000 | } |
1006 | 1001 | |
1007 | 1002 | static int snd_pcm_rate_htimestamp(snd_pcm_t *pcm, |
1059 | 1054 | sw_params.avail_min = 1; |
1060 | 1055 | snd_pcm_sw_params(rate->gen.slave, &sw_params); |
1061 | 1056 | |
1062 | size = rate->appl_ptr - rate->last_commit_ptr; | |
1063 | if (size > pcm->boundary) | |
1064 | size -= pcm->boundary; | |
1057 | size = pcm_frame_diff(rate->appl_ptr, rate->last_commit_ptr, pcm->boundary); | |
1065 | 1058 | ofs = rate->last_commit_ptr % pcm->buffer_size; |
1066 | 1059 | while (size > 0) { |
1067 | 1060 | snd_pcm_uframes_t psize, spsize; |
1163 | 1156 | status->avail = snd_pcm_mmap_playback_avail(pcm); |
1164 | 1157 | status->avail_max = rate->ops.input_frames(rate->obj, status->avail_max); |
1165 | 1158 | } else { |
1166 | /* FIXME: Maybe possible to somthing similar to | |
1167 | * snd_pcm_rate_playback_internal_delay() | |
1168 | * for the capture case. | |
1169 | */ | |
1170 | 1159 | status->delay = rate->ops.output_frames(rate->obj, status->delay) |
1171 | + snd_pcm_mmap_capture_hw_avail(pcm); | |
1160 | + snd_pcm_mmap_capture_delay(pcm); | |
1172 | 1161 | status->avail = snd_pcm_mmap_capture_avail(pcm); |
1173 | 1162 | status->avail_max = rate->ops.output_frames(rate->obj, status->avail_max); |
1174 | 1163 | } |
710 | 710 | _notrunning: |
711 | 711 | status->delay = sd + d; |
712 | 712 | status->state = share->state; |
713 | status->appl_ptr = *pcm->appl.ptr; | |
714 | status->hw_ptr = *pcm->hw.ptr; | |
713 | 715 | status->trigger_tstamp = share->trigger_tstamp; |
714 | 716 | _end: |
715 | 717 | Pthread_mutex_unlock(&slave->mutex); |
706 | 706 | snd_pcm_dump(svol->plug.gen.slave, out); |
707 | 707 | } |
708 | 708 | |
709 | static int add_tlv_info(snd_pcm_softvol_t *svol, snd_ctl_elem_info_t *cinfo) | |
709 | static int add_tlv_info(snd_pcm_softvol_t *svol, snd_ctl_elem_info_t *cinfo, | |
710 | unsigned int *old_tlv, size_t old_tlv_size) | |
710 | 711 | { |
711 | 712 | unsigned int tlv[4]; |
712 | 713 | tlv[SNDRV_CTL_TLVO_TYPE] = SND_CTL_TLVT_DB_SCALE; |
714 | 715 | tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] = (int)(svol->min_dB * 100); |
715 | 716 | tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] = |
716 | 717 | (int)((svol->max_dB - svol->min_dB) * 100 / svol->max_val); |
718 | if (sizeof(tlv) <= old_tlv_size && memcmp(tlv, old_tlv, sizeof(tlv)) == 0) | |
719 | return 0; | |
717 | 720 | return snd_ctl_elem_tlv_write(svol->ctl, &cinfo->id, tlv); |
718 | 721 | } |
719 | 722 | |
724 | 727 | int i; |
725 | 728 | unsigned int def_val; |
726 | 729 | |
727 | if (svol->max_val == 1) | |
730 | if (svol->max_val == 1) { | |
731 | snd_ctl_elem_info_set_read_write(cinfo, 1, 1); | |
728 | 732 | err = snd_ctl_add_boolean_elem_set(svol->ctl, cinfo, 1, count); |
729 | else | |
733 | } else { | |
730 | 734 | err = snd_ctl_add_integer_elem_set(svol->ctl, cinfo, 1, count, |
731 | 735 | 0, svol->max_val, 0); |
736 | } | |
732 | 737 | if (err < 0) |
733 | 738 | return err; |
734 | 739 | if (svol->max_val == 1) |
735 | 740 | def_val = 1; |
736 | 741 | else { |
737 | add_tlv_info(svol, cinfo); | |
742 | add_tlv_info(svol, cinfo, NULL, 0); | |
738 | 743 | /* set zero dB value as default, or max_val if |
739 | 744 | there is no 0 dB setting */ |
740 | 745 | def_val = svol->zero_dB_val ? svol->zero_dB_val : svol->max_val; |
810 | 815 | cinfo.type != SND_CTL_ELEM_TYPE_BOOLEAN) || |
811 | 816 | cinfo.count != (unsigned int)cchannels || |
812 | 817 | cinfo.value.integer.min != 0 || |
813 | cinfo.value.integer.max != resolution - 1) { | |
818 | cinfo.value.integer.max != svol->max_val || | |
819 | (svol->max_val > 1 && | |
820 | (cinfo.access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) == 0) || | |
821 | (svol->max_val < 2 && | |
822 | (cinfo.access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) != 0)) { | |
814 | 823 | err = snd_ctl_elem_remove(svol->ctl, &cinfo.id); |
815 | 824 | if (err < 0) { |
816 | 825 | SNDERR("Control %s mismatch", tmp_name); |
817 | 826 | return err; |
818 | 827 | } |
819 | /* reset numid */ | |
828 | /* clear cinfo including numid */ | |
829 | snd_ctl_elem_info_clear(&cinfo); | |
820 | 830 | snd_ctl_elem_info_set_id(&cinfo, ctl_id); |
821 | 831 | if ((err = add_user_ctl(svol, &cinfo, cchannels)) < 0) { |
822 | 832 | SNDERR("Cannot add a control"); |
827 | 837 | unsigned int tlv[4]; |
828 | 838 | err = snd_ctl_elem_tlv_read(svol->ctl, &cinfo.id, tlv, |
829 | 839 | sizeof(tlv)); |
830 | if (err < 0) | |
831 | add_tlv_info(svol, &cinfo); | |
840 | add_tlv_info(svol, &cinfo, tlv, err < 0 ? 0 : sizeof(tlv)); | |
832 | 841 | } |
833 | 842 | } |
834 | 843 | |
973 | 982 | return 0; |
974 | 983 | } |
975 | 984 | |
976 | /* in pcm_misc.c */ | |
977 | int snd_pcm_parse_control_id(snd_config_t *conf, snd_ctl_elem_id_t *ctl_id, int *cardp, | |
978 | int *cchannelsp, int *hwctlp); | |
985 | int _snd_pcm_parse_control_id(snd_config_t *conf, snd_ctl_elem_id_t *ctl_id, | |
986 | int *cardp, int *cchannels) | |
987 | { | |
988 | snd_config_iterator_t i, next; | |
989 | int iface = SND_CTL_ELEM_IFACE_MIXER; | |
990 | const char *name = NULL; | |
991 | long index = 0; | |
992 | long device = -1; | |
993 | long subdevice = -1; | |
994 | int err; | |
995 | ||
996 | assert(ctl_id && cardp && cchannels); | |
997 | ||
998 | *cardp = -1; | |
999 | *cchannels = 2; | |
1000 | snd_config_for_each(i, next, conf) { | |
1001 | snd_config_t *n = snd_config_iterator_entry(i); | |
1002 | const char *id; | |
1003 | if (snd_config_get_id(n, &id) < 0) | |
1004 | continue; | |
1005 | if (strcmp(id, "comment") == 0) | |
1006 | continue; | |
1007 | if (strcmp(id, "card") == 0) { | |
1008 | err = snd_config_get_card(n); | |
1009 | if (err < 0) | |
1010 | goto _err; | |
1011 | *cardp = err; | |
1012 | continue; | |
1013 | } | |
1014 | if (strcmp(id, "iface") == 0 || strcmp(id, "interface") == 0) { | |
1015 | err = snd_config_get_ctl_iface(n); | |
1016 | if (err < 0) | |
1017 | goto _err; | |
1018 | iface = err; | |
1019 | continue; | |
1020 | } | |
1021 | if (strcmp(id, "name") == 0) { | |
1022 | if ((err = snd_config_get_string(n, &name)) < 0) { | |
1023 | SNDERR("field %s is not a string", id); | |
1024 | goto _err; | |
1025 | } | |
1026 | continue; | |
1027 | } | |
1028 | if (strcmp(id, "index") == 0) { | |
1029 | if ((err = snd_config_get_integer(n, &index)) < 0) { | |
1030 | SNDERR("field %s is not an integer", id); | |
1031 | goto _err; | |
1032 | } | |
1033 | continue; | |
1034 | } | |
1035 | if (strcmp(id, "device") == 0) { | |
1036 | if ((err = snd_config_get_integer(n, &device)) < 0) { | |
1037 | SNDERR("field %s is not an integer", id); | |
1038 | goto _err; | |
1039 | } | |
1040 | continue; | |
1041 | } | |
1042 | if (strcmp(id, "subdevice") == 0) { | |
1043 | if ((err = snd_config_get_integer(n, &subdevice)) < 0) { | |
1044 | SNDERR("field %s is not an integer", id); | |
1045 | goto _err; | |
1046 | } | |
1047 | continue; | |
1048 | } | |
1049 | if (strcmp(id, "count") == 0) { | |
1050 | long v; | |
1051 | if ((err = snd_config_get_integer(n, &v)) < 0) { | |
1052 | SNDERR("field %s is not an integer", id); | |
1053 | goto _err; | |
1054 | } | |
1055 | if (v < 1 || v > 2) { | |
1056 | SNDERR("Invalid count %ld", v); | |
1057 | goto _err; | |
1058 | } | |
1059 | *cchannels = v; | |
1060 | continue; | |
1061 | } | |
1062 | SNDERR("Unknown field %s", id); | |
1063 | return -EINVAL; | |
1064 | } | |
1065 | if (name == NULL) { | |
1066 | SNDERR("Missing control name"); | |
1067 | err = -EINVAL; | |
1068 | goto _err; | |
1069 | } | |
1070 | if (device < 0) | |
1071 | device = 0; | |
1072 | if (subdevice < 0) | |
1073 | subdevice = 0; | |
1074 | ||
1075 | snd_ctl_elem_id_set_interface(ctl_id, iface); | |
1076 | snd_ctl_elem_id_set_name(ctl_id, name); | |
1077 | snd_ctl_elem_id_set_index(ctl_id, index); | |
1078 | snd_ctl_elem_id_set_device(ctl_id, device); | |
1079 | snd_ctl_elem_id_set_subdevice(ctl_id, subdevice); | |
1080 | ||
1081 | return 0; | |
1082 | ||
1083 | _err: | |
1084 | return err; | |
1085 | } | |
979 | 1086 | |
980 | 1087 | /*! \page pcm_plugins |
981 | 1088 | |
1148 | 1255 | snd_config_delete(sconf); |
1149 | 1256 | if (err < 0) |
1150 | 1257 | return err; |
1151 | err = snd_pcm_parse_control_id(control, &ctl_id, &card, | |
1152 | &cchannels, NULL); | |
1258 | err = _snd_pcm_parse_control_id(control, &ctl_id, &card, &cchannels); | |
1153 | 1259 | if (err < 0) { |
1154 | 1260 | snd_pcm_close(spcm); |
1155 | 1261 | return err; |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
326 | 326 | prefix = @prefix@ |
327 | 327 | program_transform_name = @program_transform_name@ |
328 | 328 | psdir = @psdir@ |
329 | runstatedir = @runstatedir@ | |
329 | 330 | sbindir = @sbindir@ |
330 | 331 | sharedstatedir = @sharedstatedir@ |
331 | 332 | srcdir = @srcdir@ |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
302 | 302 | prefix = @prefix@ |
303 | 303 | program_transform_name = @program_transform_name@ |
304 | 304 | psdir = @psdir@ |
305 | runstatedir = @runstatedir@ | |
305 | 306 | sbindir = @sbindir@ |
306 | 307 | sharedstatedir = @sharedstatedir@ |
307 | 308 | srcdir = @srcdir@ |
303 | 303 | int err; |
304 | 304 | |
305 | 305 | assert((inputp || outputp) && name); |
306 | err = snd_config_update_ref(&top); | |
307 | if (err < 0) | |
308 | return err; | |
306 | if (_snd_is_ucm_device(name)) { | |
307 | name = uc_mgr_alibcfg_by_device(&top, name); | |
308 | if (name == NULL) | |
309 | return -ENODEV; | |
310 | } else { | |
311 | err = snd_config_update_ref(&top); | |
312 | if (err < 0) | |
313 | return err; | |
314 | } | |
309 | 315 | err = snd_rawmidi_open_noupdate(inputp, outputp, top, name, mode); |
310 | 316 | snd_config_unref(top); |
311 | 317 | return err; |
320 | 320 | { |
321 | 321 | snd_config_iterator_t i, next; |
322 | 322 | long card = -1, device = 0, subdevice = -1; |
323 | const char *str; | |
324 | 323 | int err; |
325 | 324 | snd_config_for_each(i, next, conf) { |
326 | 325 | snd_config_t *n = snd_config_iterator_entry(i); |
330 | 329 | if (snd_rawmidi_conf_generic_id(id)) |
331 | 330 | continue; |
332 | 331 | if (strcmp(id, "card") == 0) { |
333 | err = snd_config_get_integer(n, &card); | |
334 | if (err < 0) { | |
335 | err = snd_config_get_string(n, &str); | |
336 | if (err < 0) | |
337 | return -EINVAL; | |
338 | card = snd_card_get_index(str); | |
339 | if (card < 0) | |
340 | return card; | |
341 | } | |
332 | err = snd_config_get_card(n); | |
333 | if (err < 0) | |
334 | return err; | |
335 | card = err; | |
342 | 336 | continue; |
343 | 337 | } |
344 | 338 | if (strcmp(id, "device") == 0) { |
314 | 314 | int merge, int mode) |
315 | 315 | { |
316 | 316 | int err; |
317 | snd_rawmidi_t *rmidi; | |
317 | snd_rawmidi_t *rmidi = NULL; | |
318 | 318 | snd_rawmidi_virtual_t *virt = NULL; |
319 | 319 | struct pollfd pfd; |
320 | 320 | |
391 | 391 | free(*inputp); |
392 | 392 | if (outputp) |
393 | 393 | free(*outputp); |
394 | free(rmidi); | |
394 | 395 | return err; |
395 | 396 | } |
396 | 397 |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
303 | 303 | prefix = @prefix@ |
304 | 304 | program_transform_name = @program_transform_name@ |
305 | 305 | psdir = @psdir@ |
306 | runstatedir = @runstatedir@ | |
306 | 307 | sbindir = @sbindir@ |
307 | 308 | sharedstatedir = @sharedstatedir@ |
308 | 309 | srcdir = @srcdir@ |
977 | 977 | int err; |
978 | 978 | |
979 | 979 | assert(seqp && name); |
980 | err = snd_config_update_ref(&top); | |
981 | if (err < 0) | |
982 | return err; | |
980 | if (_snd_is_ucm_device(name)) { | |
981 | name = uc_mgr_alibcfg_by_device(&top, name); | |
982 | if (name == NULL) | |
983 | return -ENODEV; | |
984 | } else { | |
985 | err = snd_config_update_ref(&top); | |
986 | if (err < 0) | |
987 | return err; | |
988 | } | |
983 | 989 | err = snd_seq_open_noupdate(seqp, top, name, streams, mode, 0); |
984 | 990 | snd_config_unref(top); |
985 | 991 | return err; |
387 | 387 | */ |
388 | 388 | int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *arg) |
389 | 389 | { |
390 | char *p; | |
391 | int client, port; | |
390 | char *p, *buf; | |
391 | const char *s; | |
392 | char c; | |
393 | long client, port = 0; | |
392 | 394 | int len; |
393 | 395 | |
394 | 396 | assert(addr && arg); |
395 | 397 | |
396 | if ((p = strpbrk(arg, ":.")) != NULL) { | |
397 | if ((port = atoi(p + 1)) < 0) | |
398 | return -EINVAL; | |
399 | len = (int)(p - arg); /* length of client name */ | |
398 | c = *arg; | |
399 | if (c == '"' || c == '\'') { | |
400 | s = ++arg; | |
401 | while (*s && *s != c) s++; | |
402 | len = s - arg; | |
403 | if (*s) | |
404 | s++; | |
405 | if (*s) { | |
406 | if (*s != '.' && *s != ':') | |
407 | return -EINVAL; | |
408 | if ((port = atoi(s + 1)) < 0) | |
409 | return -EINVAL; | |
410 | } | |
400 | 411 | } else { |
401 | port = 0; | |
402 | len = strlen(arg); | |
412 | if ((p = strpbrk(arg, ":.")) != NULL) { | |
413 | if ((port = atoi(p + 1)) < 0) | |
414 | return -EINVAL; | |
415 | len = (int)(p - arg); /* length of client name */ | |
416 | } else { | |
417 | len = strlen(arg); | |
418 | } | |
403 | 419 | } |
420 | if (len == 0) | |
421 | return -EINVAL; | |
422 | buf = alloca(len + 1); | |
423 | strncpy(buf, arg, len); | |
424 | buf[len] = '\0'; | |
404 | 425 | addr->port = port; |
405 | if (isdigit(*arg)) { | |
406 | client = atoi(arg); | |
407 | if (client < 0) | |
408 | return -EINVAL; | |
426 | if (safe_strtol(buf, &client) == 0) { | |
409 | 427 | addr->client = client; |
410 | 428 | } else { |
411 | 429 | /* convert from the name */ |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
298 | 298 | prefix = @prefix@ |
299 | 299 | program_transform_name = @program_transform_name@ |
300 | 300 | psdir = @psdir@ |
301 | runstatedir = @runstatedir@ | |
301 | 302 | sbindir = @sbindir@ |
302 | 303 | sharedstatedir = @sharedstatedir@ |
303 | 304 | srcdir = @srcdir@ |
204 | 204 | int err; |
205 | 205 | |
206 | 206 | assert(timer && name); |
207 | err = snd_config_update_ref(&top); | |
208 | if (err < 0) | |
209 | return err; | |
207 | if (_snd_is_ucm_device(name)) { | |
208 | name = uc_mgr_alibcfg_by_device(&top, name); | |
209 | if (name == NULL) | |
210 | return -ENODEV; | |
211 | } else { | |
212 | err = snd_config_update_ref(&top); | |
213 | if (err < 0) | |
214 | return err; | |
215 | } | |
210 | 216 | err = snd_timer_open_noupdate(timer, top, name, mode); |
211 | 217 | snd_config_unref(top); |
212 | 218 | return err; |
287 | 287 | snd_config_iterator_t i, next; |
288 | 288 | long dev_class = SND_TIMER_CLASS_GLOBAL, dev_sclass = SND_TIMER_SCLASS_NONE; |
289 | 289 | long card = 0, device = 0, subdevice = 0; |
290 | const char *str; | |
291 | 290 | int err; |
292 | 291 | snd_config_for_each(i, next, conf) { |
293 | 292 | snd_config_t *n = snd_config_iterator_entry(i); |
309 | 308 | continue; |
310 | 309 | } |
311 | 310 | if (strcmp(id, "card") == 0) { |
312 | err = snd_config_get_integer(n, &card); | |
313 | if (err < 0) { | |
314 | err = snd_config_get_string(n, &str); | |
315 | if (err < 0) | |
316 | return -EINVAL; | |
317 | card = snd_card_get_index(str); | |
318 | if (card < 0) | |
319 | return card; | |
320 | } | |
311 | err = snd_config_get_card(n); | |
312 | if (err < 0) | |
313 | return err; | |
314 | card = err; | |
321 | 315 | continue; |
322 | 316 | } |
323 | 317 | if (strcmp(id, "device") == 0) { |
335 | 329 | SNDERR("Unexpected field %s", id); |
336 | 330 | return -EINVAL; |
337 | 331 | } |
338 | if (card < 0) | |
339 | return -EINVAL; | |
340 | 332 | return snd_timer_hw_open(timer, name, dev_class, dev_sclass, card, device, subdevice, mode); |
341 | 333 | } |
342 | 334 | SND_DLSYM_BUILD_VERSION(_snd_timer_hw_open, SND_TIMER_DLSYM_VERSION); |
103 | 103 | close(fd); |
104 | 104 | return -SND_ERROR_INCOMPATIBLE_VERSION; |
105 | 105 | } |
106 | tmr = (snd_timer_query_t *) calloc(1, sizeof(snd_timer_t)); | |
106 | tmr = (snd_timer_query_t *) calloc(1, sizeof(snd_timer_query_t)); | |
107 | 107 | if (tmr == NULL) { |
108 | 108 | close(fd); |
109 | 109 | return -ENOMEM; |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
335 | 335 | prefix = @prefix@ |
336 | 336 | program_transform_name = @program_transform_name@ |
337 | 337 | psdir = @psdir@ |
338 | runstatedir = @runstatedir@ | |
338 | 339 | sbindir = @sbindir@ |
339 | 340 | sharedstatedir = @sharedstatedir@ |
340 | 341 | srcdir = @srcdir@ |
835 | 835 | default: |
836 | 836 | SNDERR("widget %s: invalid type %d for ctl %d", |
837 | 837 | wt->name, ct->type, i); |
838 | ret = -EINVAL; | |
838 | 839 | break; |
839 | 840 | } |
840 | 841 |
858 | 858 | goto err; |
859 | 859 | } |
860 | 860 | |
861 | if ((type == SND_SOC_TPLG_TUPLE_TYPE_WORD | |
862 | && tuple_val > UINT_MAX) | |
863 | || (type == SND_SOC_TPLG_TUPLE_TYPE_SHORT | |
864 | && tuple_val > USHRT_MAX) | |
865 | || (type == SND_SOC_TPLG_TUPLE_TYPE_BYTE | |
861 | if (/* (type == SND_SOC_TPLG_TUPLE_TYPE_WORD | |
862 | && tuple_val > UINT_MAX) || */ | |
863 | (type == SND_SOC_TPLG_TUPLE_TYPE_SHORT | |
864 | && tuple_val > USHRT_MAX) || | |
865 | (type == SND_SOC_TPLG_TUPLE_TYPE_BYTE | |
866 | 866 | && tuple_val > UCHAR_MAX)) { |
867 | 867 | SNDERR("tuple %s: invalid value", id); |
868 | 868 | goto err; |
1366 | 1366 | .name = "AC97", |
1367 | 1367 | }, |
1368 | 1368 | { |
1369 | .type = SND_SOC_DAI_FORMAT_AC97, | |
1370 | .name = "AC97", | |
1371 | }, | |
1372 | { | |
1373 | 1369 | .type = SND_SOC_DAI_FORMAT_PDM, |
1374 | 1370 | .name = "PDM", |
1375 | 1371 | }, |
1410 | 1406 | snd_config_t *n; |
1411 | 1407 | const char *id, *val = NULL; |
1412 | 1408 | int ret, ival; |
1409 | bool provider_legacy; | |
1413 | 1410 | |
1414 | 1411 | elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_HW_CONFIG); |
1415 | 1412 | if (!elem) |
1450 | 1447 | continue; |
1451 | 1448 | } |
1452 | 1449 | |
1453 | if (strcmp(id, "bclk") == 0 || | |
1454 | strcmp(id, "bclk_master") == 0) { | |
1450 | provider_legacy = false; | |
1451 | if (strcmp(id, "bclk_master") == 0) { | |
1452 | SNDERR("deprecated option %s, please use 'bclk'\n", id); | |
1453 | provider_legacy = true; | |
1454 | } | |
1455 | ||
1456 | if (provider_legacy || | |
1457 | strcmp(id, "bclk") == 0) { | |
1458 | ||
1455 | 1459 | if (snd_config_get_string(n, &val) < 0) |
1456 | 1460 | return -EINVAL; |
1457 | 1461 | |
1461 | 1465 | */ |
1462 | 1466 | SNDERR("deprecated bclk value '%s'", val); |
1463 | 1467 | |
1464 | hw_cfg->bclk_master = SND_SOC_TPLG_BCLK_CS; | |
1468 | hw_cfg->bclk_provider = SND_SOC_TPLG_BCLK_CC; | |
1465 | 1469 | } else if (!strcmp(val, "codec_slave")) { |
1466 | hw_cfg->bclk_master = SND_SOC_TPLG_BCLK_CS; | |
1470 | SNDERR("deprecated bclk value '%s', use 'codec_consumer'", val); | |
1471 | ||
1472 | hw_cfg->bclk_provider = SND_SOC_TPLG_BCLK_CC; | |
1473 | } else if (!strcmp(val, "codec_consumer")) { | |
1474 | hw_cfg->bclk_provider = SND_SOC_TPLG_BCLK_CC; | |
1467 | 1475 | } else if (!strcmp(val, "codec_master")) { |
1468 | hw_cfg->bclk_master = SND_SOC_TPLG_BCLK_CM; | |
1476 | SNDERR("deprecated bclk value '%s', use 'codec_provider", val); | |
1477 | ||
1478 | hw_cfg->bclk_provider = SND_SOC_TPLG_BCLK_CP; | |
1479 | } else if (!strcmp(val, "codec_provider")) { | |
1480 | hw_cfg->bclk_provider = SND_SOC_TPLG_BCLK_CP; | |
1469 | 1481 | } |
1470 | 1482 | continue; |
1471 | 1483 | } |
1487 | 1499 | continue; |
1488 | 1500 | } |
1489 | 1501 | |
1490 | if (strcmp(id, "fsync") == 0 || | |
1491 | strcmp(id, "fsync_master") == 0) { | |
1502 | provider_legacy = false; | |
1503 | if (strcmp(id, "fsync_master") == 0) { | |
1504 | SNDERR("deprecated option %s, please use 'fsync'\n", id); | |
1505 | provider_legacy = true; | |
1506 | } | |
1507 | ||
1508 | if (provider_legacy || | |
1509 | strcmp(id, "fsync") == 0) { | |
1510 | ||
1492 | 1511 | if (snd_config_get_string(n, &val) < 0) |
1493 | 1512 | return -EINVAL; |
1494 | 1513 | |
1498 | 1517 | */ |
1499 | 1518 | SNDERR("deprecated fsync value '%s'", val); |
1500 | 1519 | |
1501 | hw_cfg->fsync_master = SND_SOC_TPLG_FSYNC_CS; | |
1520 | hw_cfg->fsync_provider = SND_SOC_TPLG_FSYNC_CC; | |
1502 | 1521 | } else if (!strcmp(val, "codec_slave")) { |
1503 | hw_cfg->fsync_master = SND_SOC_TPLG_FSYNC_CS; | |
1522 | SNDERR("deprecated fsync value '%s', use 'codec_consumer'", val); | |
1523 | ||
1524 | hw_cfg->fsync_provider = SND_SOC_TPLG_FSYNC_CC; | |
1525 | } else if (!strcmp(val, "codec_consumer")) { | |
1526 | hw_cfg->fsync_provider = SND_SOC_TPLG_FSYNC_CC; | |
1504 | 1527 | } else if (!strcmp(val, "codec_master")) { |
1505 | hw_cfg->fsync_master = SND_SOC_TPLG_FSYNC_CM; | |
1528 | SNDERR("deprecated fsync value '%s', use 'codec_provider'", val); | |
1529 | ||
1530 | hw_cfg->fsync_provider = SND_SOC_TPLG_FSYNC_CP; | |
1531 | } else if (!strcmp(val, "codec_provider")) { | |
1532 | hw_cfg->fsync_provider = SND_SOC_TPLG_FSYNC_CP; | |
1506 | 1533 | } |
1507 | 1534 | continue; |
1508 | 1535 | } |
1622 | 1649 | if (err >= 0 && hc->fmt) |
1623 | 1650 | err = tplg_save_printf(dst, pfx, "\tformat '%s'\n", |
1624 | 1651 | get_audio_hw_format_name(hc->fmt)); |
1625 | if (err >= 0 && hc->bclk_master) | |
1652 | if (err >= 0 && hc->bclk_provider) | |
1626 | 1653 | err = tplg_save_printf(dst, pfx, "\tbclk '%s'\n", |
1627 | hc->bclk_master == SND_SOC_TPLG_BCLK_CS ? | |
1628 | "codec_slave" : "codec_master"); | |
1654 | hc->bclk_provider == SND_SOC_TPLG_BCLK_CC ? | |
1655 | "codec_consumer" : "codec_provider"); | |
1629 | 1656 | if (err >= 0 && hc->bclk_rate) |
1630 | 1657 | err = tplg_save_printf(dst, pfx, "\tbclk_freq %u\n", |
1631 | 1658 | hc->bclk_rate); |
1632 | 1659 | if (err >= 0 && hc->invert_bclk) |
1633 | 1660 | err = tplg_save_printf(dst, pfx, "\tbclk_invert 1\n"); |
1634 | if (err >= 0 && hc->fsync_master) | |
1635 | err = tplg_save_printf(dst, pfx, "\tfsync_master '%s'\n", | |
1636 | hc->fsync_master == SND_SOC_TPLG_FSYNC_CS ? | |
1637 | "codec_slave" : "codec_master"); | |
1661 | if (err >= 0 && hc->fsync_provider) | |
1662 | err = tplg_save_printf(dst, pfx, "\tfsync_provider '%s'\n", | |
1663 | hc->fsync_provider == SND_SOC_TPLG_FSYNC_CC ? | |
1664 | "codec_consumer" : "codec_provider"); | |
1638 | 1665 | if (err >= 0 && hc->fsync_rate) |
1639 | 1666 | err = tplg_save_printf(dst, pfx, "\tfsync_freq %u\n", |
1640 | 1667 | hc->fsync_rate); |
1790 | 1817 | cfg->clock_gated = tpl->clock_gated; |
1791 | 1818 | cfg->invert_bclk = tpl->invert_bclk; |
1792 | 1819 | cfg->invert_fsync = tpl->invert_fsync; |
1793 | cfg->bclk_master = tpl->bclk_master; | |
1794 | cfg->fsync_master = tpl->fsync_master; | |
1820 | cfg->bclk_provider = tpl->bclk_provider; | |
1821 | cfg->fsync_provider = tpl->fsync_provider; | |
1795 | 1822 | cfg->mclk_direction = tpl->mclk_direction; |
1796 | 1823 | cfg->reserved = tpl->reserved; |
1797 | 1824 | cfg->mclk_rate = tpl->mclk_rate; |
1988 | 2015 | pt->playback = pcm->playback; |
1989 | 2016 | pt->capture = pcm->capture; |
1990 | 2017 | pt->compress = pcm->compress; |
1991 | tplg_log(tplg, 'D', pos, "pcm: playback %d capture %d compress", | |
2018 | tplg_log(tplg, 'D', pos, "pcm: playback %d capture %d compress %d", | |
1992 | 2019 | pt->playback, pt->capture, pt->compress); |
1993 | 2020 | pt->num_streams = pcm->num_streams; |
1994 | 2021 | pt->flag_mask = pcm->flag_mask; |
2173 | 2200 | hw->clock_gated = link->hw_config[i].clock_gated; |
2174 | 2201 | hw->invert_bclk = link->hw_config[i].invert_bclk; |
2175 | 2202 | hw->invert_fsync = link->hw_config[i].invert_fsync; |
2176 | hw->bclk_master = link->hw_config[i].bclk_master; | |
2177 | hw->fsync_master = link->hw_config[i].fsync_master; | |
2203 | hw->bclk_provider = link->hw_config[i].bclk_provider; | |
2204 | hw->fsync_provider = link->hw_config[i].fsync_provider; | |
2178 | 2205 | hw->mclk_direction = link->hw_config[i].mclk_direction; |
2179 | 2206 | hw->mclk_rate = link->hw_config[i].mclk_rate; |
2180 | 2207 | hw->bclk_rate = link->hw_config[i].bclk_rate; |
132 | 132 | if (llval < INT_MIN || llval > UINT_MAX) |
133 | 133 | return snd_config_get_ascii(n, ret); |
134 | 134 | lval = llval; |
135 | } else { | |
136 | lval = 0; | |
135 | 137 | } |
136 | 138 | err = tplg_nice_value_format(buf, sizeof(buf), (unsigned int)lval); |
137 | 139 | if (err < 0) |
177 | 179 | } |
178 | 180 | if (array <= 0) |
179 | 181 | qsort(a, count, sizeof(a[0]), _compar); |
180 | if (snd_config_make_compound(&dst, id, count == 1)) { | |
181 | free(a); | |
182 | return NULL; | |
183 | } | |
182 | if (snd_config_make_compound(&dst, id, count == 1)) | |
183 | goto lerr; | |
184 | 184 | for (index = 0; index < count; index++) { |
185 | 185 | snd_config_t *s = a[index]; |
186 | 186 | const char *id2; |
187 | 187 | if (snd_config_get_id(s, &id2)) { |
188 | 188 | snd_config_delete(dst); |
189 | free(a); | |
190 | return NULL; | |
189 | goto lerr; | |
191 | 190 | } |
192 | 191 | s = sort_config(id2, s); |
193 | 192 | if (s == NULL || snd_config_add(dst, s)) { |
194 | 193 | if (s) |
195 | 194 | snd_config_delete(s); |
196 | 195 | snd_config_delete(dst); |
197 | free(a); | |
198 | return NULL; | |
196 | goto lerr; | |
199 | 197 | } |
200 | 198 | } |
201 | 199 | free(a); |
202 | 200 | return dst; |
201 | lerr: | |
202 | free(a); | |
203 | return NULL; | |
203 | 204 | } |
204 | 205 | |
205 | 206 | static int tplg_check_quoted(const unsigned char *p) |
0 | 0 | EXTRA_LTLIBRARIES = libucm.la |
1 | 1 | |
2 | 2 | libucm_la_SOURCES = utils.c parser.c ucm_cond.c ucm_subs.c ucm_include.c \ |
3 | ucm_regex.c main.c | |
3 | ucm_regex.c ucm_exec.c main.c | |
4 | 4 | |
5 | 5 | noinst_HEADERS = ucm_local.h |
6 | 6 |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
104 | 104 | CONFIG_CLEAN_VPATH_FILES = |
105 | 105 | libucm_la_LIBADD = |
106 | 106 | am_libucm_la_OBJECTS = utils.lo parser.lo ucm_cond.lo ucm_subs.lo \ |
107 | ucm_include.lo ucm_regex.lo main.lo | |
107 | ucm_include.lo ucm_regex.lo ucm_exec.lo main.lo | |
108 | 108 | libucm_la_OBJECTS = $(am_libucm_la_OBJECTS) |
109 | 109 | AM_V_lt = $(am__v_lt_@AM_V@) |
110 | 110 | am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) |
126 | 126 | depcomp = $(SHELL) $(top_srcdir)/depcomp |
127 | 127 | am__maybe_remake_depfiles = depfiles |
128 | 128 | am__depfiles_remade = ./$(DEPDIR)/main.Plo ./$(DEPDIR)/parser.Plo \ |
129 | ./$(DEPDIR)/ucm_cond.Plo ./$(DEPDIR)/ucm_include.Plo \ | |
130 | ./$(DEPDIR)/ucm_regex.Plo ./$(DEPDIR)/ucm_subs.Plo \ | |
131 | ./$(DEPDIR)/utils.Plo | |
129 | ./$(DEPDIR)/ucm_cond.Plo ./$(DEPDIR)/ucm_exec.Plo \ | |
130 | ./$(DEPDIR)/ucm_include.Plo ./$(DEPDIR)/ucm_regex.Plo \ | |
131 | ./$(DEPDIR)/ucm_subs.Plo ./$(DEPDIR)/utils.Plo | |
132 | 132 | am__mv = mv -f |
133 | 133 | COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ |
134 | 134 | $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
299 | 299 | prefix = @prefix@ |
300 | 300 | program_transform_name = @program_transform_name@ |
301 | 301 | psdir = @psdir@ |
302 | runstatedir = @runstatedir@ | |
302 | 303 | sbindir = @sbindir@ |
303 | 304 | sharedstatedir = @sharedstatedir@ |
304 | 305 | srcdir = @srcdir@ |
309 | 310 | top_srcdir = @top_srcdir@ |
310 | 311 | EXTRA_LTLIBRARIES = libucm.la |
311 | 312 | libucm_la_SOURCES = utils.c parser.c ucm_cond.c ucm_subs.c ucm_include.c \ |
312 | ucm_regex.c main.c | |
313 | ucm_regex.c ucm_exec.c main.c | |
313 | 314 | |
314 | 315 | noinst_HEADERS = ucm_local.h |
315 | 316 | AM_CPPFLAGS = -I$(top_srcdir)/include |
359 | 360 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@ # am--include-marker |
360 | 361 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Plo@am__quote@ # am--include-marker |
361 | 362 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ucm_cond.Plo@am__quote@ # am--include-marker |
363 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ucm_exec.Plo@am__quote@ # am--include-marker | |
362 | 364 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ucm_include.Plo@am__quote@ # am--include-marker |
363 | 365 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ucm_regex.Plo@am__quote@ # am--include-marker |
364 | 366 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ucm_subs.Plo@am__quote@ # am--include-marker |
524 | 526 | -rm -f ./$(DEPDIR)/main.Plo |
525 | 527 | -rm -f ./$(DEPDIR)/parser.Plo |
526 | 528 | -rm -f ./$(DEPDIR)/ucm_cond.Plo |
529 | -rm -f ./$(DEPDIR)/ucm_exec.Plo | |
527 | 530 | -rm -f ./$(DEPDIR)/ucm_include.Plo |
528 | 531 | -rm -f ./$(DEPDIR)/ucm_regex.Plo |
529 | 532 | -rm -f ./$(DEPDIR)/ucm_subs.Plo |
576 | 579 | -rm -f ./$(DEPDIR)/main.Plo |
577 | 580 | -rm -f ./$(DEPDIR)/parser.Plo |
578 | 581 | -rm -f ./$(DEPDIR)/ucm_cond.Plo |
582 | -rm -f ./$(DEPDIR)/ucm_exec.Plo | |
579 | 583 | -rm -f ./$(DEPDIR)/ucm_include.Plo |
580 | 584 | -rm -f ./$(DEPDIR)/ucm_regex.Plo |
581 | 585 | -rm -f ./$(DEPDIR)/ucm_subs.Plo |
30 | 30 | */ |
31 | 31 | |
32 | 32 | #include "ucm_local.h" |
33 | #include "../control/control_local.h" | |
34 | #include <stdbool.h> | |
33 | 35 | #include <ctype.h> |
34 | 36 | #include <stdarg.h> |
35 | 37 | #include <pthread.h> |
36 | 38 | #include <sys/stat.h> |
39 | #include <sys/wait.h> | |
37 | 40 | #include <limits.h> |
38 | 41 | |
39 | 42 | /* |
47 | 50 | const char *verb_name, |
48 | 51 | int exact); |
49 | 52 | static int get_value1(snd_use_case_mgr_t *uc_mgr, char **value, |
50 | struct list_head *value_list, const char *identifier); | |
53 | struct list_head *value_list, const char *identifier); | |
51 | 54 | static int get_value3(snd_use_case_mgr_t *uc_mgr, |
52 | char **value, | |
55 | char **value, | |
53 | 56 | const char *identifier, |
54 | 57 | struct list_head *value_list1, |
55 | 58 | struct list_head *value_list2, |
78 | 81 | |
79 | 82 | static int list_count(struct list_head *list) |
80 | 83 | { |
81 | struct list_head *pos; | |
82 | int count = 0; | |
83 | ||
84 | list_for_each(pos, list) { | |
85 | count += 1; | |
86 | } | |
87 | return count; | |
84 | struct list_head *pos; | |
85 | int count = 0; | |
86 | ||
87 | list_for_each(pos, list) { | |
88 | count += 1; | |
89 | } | |
90 | return count; | |
88 | 91 | } |
89 | 92 | |
90 | 93 | static int alloc_str_list(struct list_head *list, int mult, char **result[]) |
91 | 94 | { |
92 | char **res; | |
93 | int cnt; | |
94 | ||
95 | cnt = list_count(list) * mult; | |
96 | if (cnt == 0) { | |
95 | char **res; | |
96 | int cnt; | |
97 | ||
98 | cnt = list_count(list) * mult; | |
99 | if (cnt == 0) { | |
97 | 100 | *result = NULL; |
98 | return cnt; | |
99 | } | |
100 | res = calloc(mult, cnt * sizeof(char *)); | |
101 | if (res == NULL) | |
102 | return -ENOMEM; | |
103 | *result = res; | |
104 | return cnt; | |
101 | return cnt; | |
102 | } | |
103 | res = calloc(mult, cnt * sizeof(char *)); | |
104 | if (res == NULL) | |
105 | return -ENOMEM; | |
106 | *result = res; | |
107 | return cnt; | |
105 | 108 | } |
106 | 109 | |
107 | 110 | /** |
137 | 140 | */ |
138 | 141 | int snd_use_case_free_list(const char *list[], int items) |
139 | 142 | { |
140 | int i; | |
143 | int i; | |
141 | 144 | if (list == NULL) |
142 | 145 | return 0; |
143 | for (i = 0; i < items; i++) | |
146 | for (i = 0; i < items; i++) | |
144 | 147 | free((void *)list[i]); |
145 | free(list); | |
148 | free(list); | |
146 | 149 | return 0; |
147 | 150 | } |
148 | 151 | |
251 | 254 | return err; |
252 | 255 | } |
253 | 256 | |
254 | extern int __snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, | |
255 | const char *str, | |
256 | const char **ret_ptr); | |
257 | static const char *parse_type(const char *p, const char *prefix, size_t len, | |
258 | snd_ctl_elem_info_t *info) | |
259 | { | |
260 | if (strncasecmp(p, prefix, len)) | |
261 | return p; | |
262 | p += len; | |
263 | if (info->type != SND_CTL_ELEM_TYPE_NONE) | |
264 | return NULL; | |
265 | if (strncasecmp(p, "bool", sizeof("bool") - 1) == 0) | |
266 | info->type = SND_CTL_ELEM_TYPE_BOOLEAN; | |
267 | else if (strncasecmp(p, "integer64", sizeof("integer64") - 1) == 0) | |
268 | info->type = SND_CTL_ELEM_TYPE_INTEGER64; | |
269 | else if (strncasecmp(p, "int64", sizeof("int64") - 1) == 0) | |
270 | info->type = SND_CTL_ELEM_TYPE_INTEGER64; | |
271 | else if (strncasecmp(p, "int", sizeof("int") - 1) == 0) | |
272 | info->type = SND_CTL_ELEM_TYPE_INTEGER; | |
273 | else if (strncasecmp(p, "enum", sizeof("enum") - 1) == 0) | |
274 | info->type = SND_CTL_ELEM_TYPE_ENUMERATED; | |
275 | else if (strncasecmp(p, "bytes", sizeof("bytes") - 1) == 0) | |
276 | info->type = SND_CTL_ELEM_TYPE_BYTES; | |
277 | else | |
278 | return NULL; | |
279 | while (isalpha(*p)) | |
280 | p++; | |
281 | return p; | |
282 | } | |
283 | ||
284 | static const char *parse_uint(const char *p, const char *prefix, size_t len, | |
285 | unsigned int min, unsigned int max, unsigned int *rval) | |
286 | { | |
287 | long v; | |
288 | char *end; | |
289 | ||
290 | if (strncasecmp(p, prefix, len)) | |
291 | return p; | |
292 | p += len; | |
293 | v = strtol(p, &end, 0); | |
294 | if (*end != '\0' && *end != ' ' && *end != ',') { | |
295 | uc_error("unable to parse '%s'", prefix); | |
296 | return NULL; | |
297 | } | |
298 | if (v < min || v > max) { | |
299 | uc_error("value '%s' out of range %u-%u %(%ld)", min, max, v); | |
300 | return NULL; | |
301 | } | |
302 | *rval = v; | |
303 | return end; | |
304 | } | |
305 | ||
306 | static const char *parse_labels(const char *p, const char *prefix, size_t len, | |
307 | snd_ctl_elem_info_t *info) | |
308 | { | |
309 | const char *s; | |
310 | char *buf, *bp; | |
311 | size_t l; | |
312 | int c; | |
313 | ||
314 | if (info->type != SND_CTL_ELEM_TYPE_ENUMERATED) | |
315 | return NULL; | |
316 | if (strncasecmp(p, prefix, len)) | |
317 | return p; | |
318 | p += len; | |
319 | s = p; | |
320 | c = *s; | |
321 | l = 0; | |
322 | if (c == '\'' || c == '\"') { | |
323 | s++; | |
324 | while (*s && *s != c) { | |
325 | s++, l++; | |
326 | } | |
327 | if (*s == c) | |
328 | s++; | |
329 | } else { | |
330 | while (*s && *s != ',') | |
331 | l++; | |
332 | } | |
333 | if (l == 0) | |
334 | return NULL; | |
335 | buf = malloc(l + 1); | |
336 | if (buf == NULL) | |
337 | return NULL; | |
338 | memcpy(buf, p + ((c == '\'' || c == '\"') ? 1 : 0), l); | |
339 | buf[l] = '\0'; | |
340 | info->value.enumerated.items = 1; | |
341 | for (bp = buf; *bp; bp++) { | |
342 | if (*bp == ';') { | |
343 | if (bp == buf || bp[1] == ';') { | |
344 | free(buf); | |
345 | return NULL; | |
346 | } | |
347 | info->value.enumerated.items++; | |
348 | *bp = '\0'; | |
349 | } | |
350 | } | |
351 | info->value.enumerated.names_ptr = (uintptr_t)buf; | |
352 | info->value.enumerated.names_length = l + 1; | |
353 | return s; | |
354 | } | |
355 | ||
356 | static int parse_cset_new_info(snd_ctl_elem_info_t *info, const char *s, const char **pos) | |
357 | { | |
358 | const char *p = s, *op; | |
359 | ||
360 | info->count = 1; | |
361 | while (*s) { | |
362 | op = p; | |
363 | p = parse_type(p, "type=", sizeof("type=") - 1, info); | |
364 | if (p != op) | |
365 | goto next; | |
366 | p = parse_uint(p, "elements=", sizeof("elements=") - 1, 1, 128, (unsigned int *)&info->owner); | |
367 | if (p != op) | |
368 | goto next; | |
369 | p = parse_uint(p, "count=", sizeof("count=") - 1, 1, 128, &info->count); | |
370 | if (p != op) | |
371 | goto next; | |
372 | p = parse_labels(p, "labels=", sizeof("labels=") - 1, info); | |
373 | next: | |
374 | if (p == NULL) | |
375 | goto er; | |
376 | if (*p == ',') | |
377 | p++; | |
378 | if (isspace(*p)) | |
379 | break; | |
380 | if (op == p) | |
381 | goto er; | |
382 | } | |
383 | *pos = p; | |
384 | return 0; | |
385 | er: | |
386 | uc_error("unknown syntax '%s'", p); | |
387 | return -EINVAL; | |
388 | } | |
257 | 389 | |
258 | 390 | static int execute_cset(snd_ctl_t *ctl, const char *cset, unsigned int type) |
259 | 391 | { |
261 | 393 | int err; |
262 | 394 | snd_ctl_elem_id_t *id; |
263 | 395 | snd_ctl_elem_value_t *value; |
264 | snd_ctl_elem_info_t *info; | |
396 | snd_ctl_elem_info_t *info, *info2 = NULL; | |
265 | 397 | unsigned int *res = NULL; |
266 | 398 | |
267 | 399 | snd_ctl_elem_id_malloc(&id); |
273 | 405 | goto __fail; |
274 | 406 | while (*pos && isspace(*pos)) |
275 | 407 | pos++; |
408 | if (type == SEQUENCE_ELEMENT_TYPE_CSET_NEW) { | |
409 | snd_ctl_elem_info_malloc(&info2); | |
410 | snd_ctl_elem_info_set_id(info2, id); | |
411 | err = parse_cset_new_info(info2, pos, &pos); | |
412 | if (err < 0 || !*pos) { | |
413 | uc_error("undefined or wrong id config for cset-new", cset); | |
414 | err = -EINVAL; | |
415 | goto __fail; | |
416 | } | |
417 | while (*pos && isspace(*pos)) | |
418 | pos++; | |
419 | } | |
276 | 420 | if (!*pos) { |
277 | uc_error("undefined value for cset >%s<", cset); | |
421 | if (type != SEQUENCE_ELEMENT_TYPE_CTL_REMOVE) { | |
422 | uc_error("undefined value for cset >%s<", cset); | |
423 | err = -EINVAL; | |
424 | goto __fail; | |
425 | } | |
426 | } else if (type == SEQUENCE_ELEMENT_TYPE_CTL_REMOVE) { | |
427 | uc_error("extra value for ctl-remove >%s<", cset); | |
278 | 428 | err = -EINVAL; |
279 | 429 | goto __fail; |
280 | 430 | } |
431 | ||
281 | 432 | snd_ctl_elem_info_set_id(info, id); |
282 | 433 | err = snd_ctl_elem_info(ctl, info); |
283 | if (err < 0) | |
434 | if (type == SEQUENCE_ELEMENT_TYPE_CSET_NEW || | |
435 | type == SEQUENCE_ELEMENT_TYPE_CTL_REMOVE) { | |
436 | if (err >= 0) { | |
437 | err = snd_ctl_elem_remove(ctl, id); | |
438 | if (err < 0) { | |
439 | uc_error("unable to remove control"); | |
440 | err = -EINVAL; | |
441 | goto __fail; | |
442 | } | |
443 | } | |
444 | if (type == SEQUENCE_ELEMENT_TYPE_CTL_REMOVE) | |
445 | goto __ok; | |
446 | err = __snd_ctl_add_elem_set(ctl, info2, info2->owner, info2->count); | |
447 | if (err < 0) { | |
448 | uc_error("unable to create new control"); | |
449 | goto __fail; | |
450 | } | |
451 | /* new id copy */ | |
452 | snd_ctl_elem_info_get_id(info2, id); | |
453 | snd_ctl_elem_info_set_id(info, id); | |
454 | } else if (err < 0) | |
284 | 455 | goto __fail; |
285 | 456 | if (type == SEQUENCE_ELEMENT_TYPE_CSET_TLV) { |
286 | 457 | if (!snd_ctl_elem_info_is_tlv_writable(info)) { |
307 | 478 | err = snd_ctl_elem_write(ctl, value); |
308 | 479 | if (err < 0) |
309 | 480 | goto __fail; |
310 | } | |
481 | if (type == SEQUENCE_ELEMENT_TYPE_CSET_NEW) { | |
482 | unsigned int idx; | |
483 | for (idx = 1; idx < (unsigned int)info2->owner; idx++) { | |
484 | value->id.numid += 1; | |
485 | err = snd_ctl_elem_write(ctl, value); | |
486 | if (err < 0) | |
487 | goto __fail; | |
488 | } | |
489 | } | |
490 | } | |
491 | __ok: | |
311 | 492 | err = 0; |
312 | 493 | __fail: |
313 | if (id != NULL) | |
314 | free(id); | |
315 | if (value != NULL) | |
316 | free(value); | |
317 | if (info != NULL) | |
318 | free(info); | |
319 | if (res != NULL) | |
320 | free(res); | |
494 | free(id); | |
495 | free(value); | |
496 | if (info2) { | |
497 | if (info2->type == SND_CTL_ELEM_TYPE_ENUMERATED) | |
498 | free((void *)info2->value.enumerated.names_ptr); | |
499 | free(info2); | |
500 | } | |
501 | free(info); | |
502 | free(res); | |
321 | 503 | |
322 | 504 | return err; |
505 | } | |
506 | ||
507 | static int execute_sysw(const char *sysw) | |
508 | { | |
509 | char path[PATH_MAX]; | |
510 | const char *e; | |
511 | char *s, *value; | |
512 | ssize_t wlen; | |
513 | size_t len; | |
514 | int fd, myerrno; | |
515 | bool ignore_error = false; | |
516 | ||
517 | if (sysw == NULL || *sysw == '\0') | |
518 | return 0; | |
519 | ||
520 | if (sysw[0] == '-') { | |
521 | ignore_error = true; | |
522 | sysw++; | |
523 | } | |
524 | ||
525 | if (sysw[0] == ':') | |
526 | return -EINVAL; | |
527 | ||
528 | s = strdup(sysw[0] != '/' ? sysw : sysw + 1); | |
529 | if (s == NULL) | |
530 | return -ENOMEM; | |
531 | ||
532 | value = strchr(s, ':'); | |
533 | if (!value) { | |
534 | free(s); | |
535 | return -EINVAL; | |
536 | } | |
537 | *value = '\0'; | |
538 | value++; | |
539 | len = strlen(value); | |
540 | if (len < 1) { | |
541 | free(s); | |
542 | return -EINVAL; | |
543 | } | |
544 | ||
545 | e = uc_mgr_sysfs_root(); | |
546 | if (e == NULL) { | |
547 | free(s); | |
548 | return -EINVAL; | |
549 | } | |
550 | snprintf(path, sizeof(path), "%s/%s", e, s); | |
551 | ||
552 | fd = open(path, O_WRONLY|O_CLOEXEC); | |
553 | if (fd < 0) { | |
554 | free(s); | |
555 | if (ignore_error) | |
556 | return 0; | |
557 | uc_error("unable to open '%s' for write", path); | |
558 | return -EINVAL; | |
559 | } | |
560 | wlen = write(fd, value, len); | |
561 | myerrno = errno; | |
562 | close(fd); | |
563 | free(s); | |
564 | ||
565 | if (ignore_error) | |
566 | return 0; | |
567 | ||
568 | if (wlen != (ssize_t)len) { | |
569 | uc_error("unable to write '%s' to '%s': %s", value, path, strerror(myerrno)); | |
570 | return -EINVAL; | |
571 | } | |
572 | ||
573 | return 0; | |
574 | } | |
575 | ||
576 | int _snd_config_save_node_value(snd_config_t *n, snd_output_t *out, unsigned int level); | |
577 | ||
578 | static int execute_cfgsave(snd_use_case_mgr_t *uc_mgr, const char *filename) | |
579 | { | |
580 | snd_config_t *config = uc_mgr->local_config; | |
581 | char *file, *root; | |
582 | snd_output_t *out; | |
583 | bool with_root = false; | |
584 | int err = 0; | |
585 | ||
586 | file = strdup(filename); | |
587 | if (!file) | |
588 | return -ENOMEM; | |
589 | root = strchr(file, ':'); | |
590 | if (config && root) { | |
591 | *root++ = '\0'; | |
592 | if (*root == '+') { | |
593 | with_root = true; | |
594 | root++; | |
595 | } | |
596 | err = snd_config_search(config, root, &config); | |
597 | if (err < 0) { | |
598 | uc_error("Unable to find subtree '%s'", root); | |
599 | goto _err; | |
600 | } | |
601 | } | |
602 | ||
603 | err = snd_output_stdio_open(&out, file, "w+"); | |
604 | if (err < 0) { | |
605 | uc_error("unable to open file '%s': %s", file, snd_strerror(err)); | |
606 | goto _err; | |
607 | } | |
608 | if (!config || snd_config_is_empty(config)) { | |
609 | snd_output_close(out); | |
610 | goto _err; | |
611 | } | |
612 | if (with_root) { | |
613 | snd_output_printf(out, "%s ", root); | |
614 | err = _snd_config_save_node_value(config, out, 0); | |
615 | } else { | |
616 | err = snd_config_save(config, out); | |
617 | } | |
618 | snd_output_close(out); | |
619 | if (err < 0) { | |
620 | uc_error("unable to save configuration: %s", snd_strerror(err)); | |
621 | goto _err; | |
622 | } | |
623 | _err: | |
624 | free(file); | |
625 | return err; | |
626 | } | |
627 | ||
628 | static int rewrite_device_value(snd_use_case_mgr_t *uc_mgr, const char *name, char **value) | |
629 | { | |
630 | char *sval; | |
631 | size_t l; | |
632 | static const char **s, *_prefix[] = { | |
633 | "PlaybackCTL", | |
634 | "CaptureCTL", | |
635 | "PlaybackMixer", | |
636 | "CaptureMixer", | |
637 | "PlaybackPCM", | |
638 | "CapturePCM", | |
639 | NULL | |
640 | }; | |
641 | ||
642 | if (!uc_mgr_has_local_config(uc_mgr)) | |
643 | return 0; | |
644 | for (s = _prefix; *s && *value; s++) { | |
645 | if (strcmp(*s, name) != 0) | |
646 | continue; | |
647 | l = strlen(*value) + 9 + 1; | |
648 | sval = malloc(l); | |
649 | if (sval == NULL) { | |
650 | free(*value); | |
651 | *value = NULL; | |
652 | return -ENOMEM; | |
653 | } | |
654 | snprintf(sval, l, "_ucm%04X.%s", uc_mgr->ucm_card_number, *value); | |
655 | free(*value); | |
656 | *value = sval; | |
657 | break; | |
658 | } | |
659 | return 0; | |
323 | 660 | } |
324 | 661 | |
325 | 662 | /** |
339 | 676 | char *cdev = NULL; |
340 | 677 | snd_ctl_t *ctl = NULL; |
341 | 678 | struct ctl_list *ctl_list; |
679 | bool ignore_error; | |
342 | 680 | int err = 0; |
343 | 681 | |
344 | 682 | list_for_each(pos, seq) { |
348 | 686 | cdev = strdup(s->data.cdev); |
349 | 687 | if (cdev == NULL) |
350 | 688 | goto __fail_nomem; |
689 | if (rewrite_device_value(uc_mgr, "PlaybackCTL", &cdev)) | |
690 | goto __fail_nomem; | |
351 | 691 | break; |
352 | 692 | case SEQUENCE_ELEMENT_TYPE_CSET: |
353 | 693 | case SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE: |
354 | 694 | case SEQUENCE_ELEMENT_TYPE_CSET_TLV: |
695 | case SEQUENCE_ELEMENT_TYPE_CSET_NEW: | |
696 | case SEQUENCE_ELEMENT_TYPE_CTL_REMOVE: | |
355 | 697 | if (cdev == NULL && uc_mgr->in_component_domain) { |
356 | 698 | /* For sequence of a component device, use |
357 | 699 | * its parent's cdev stored by ucm manager. |
419 | 761 | goto __fail; |
420 | 762 | } |
421 | 763 | break; |
764 | case SEQUENCE_ELEMENT_TYPE_SYSSET: | |
765 | err = execute_sysw(s->data.sysw); | |
766 | if (err < 0) | |
767 | goto __fail; | |
768 | break; | |
422 | 769 | case SEQUENCE_ELEMENT_TYPE_SLEEP: |
423 | 770 | usleep(s->data.sleep); |
424 | 771 | break; |
425 | 772 | case SEQUENCE_ELEMENT_TYPE_EXEC: |
426 | err = system(s->data.exec); | |
427 | if (err < 0) | |
773 | if (s->data.exec == NULL) | |
774 | break; | |
775 | ignore_error = s->data.exec[0] == '-'; | |
776 | err = uc_mgr_exec(s->data.exec + (ignore_error ? 1 : 0)); | |
777 | if (ignore_error == false && err != 0) { | |
778 | uc_error("exec '%s' failed (exit code %d)", s->data.exec, err); | |
428 | 779 | goto __fail; |
780 | } | |
781 | break; | |
782 | case SEQUENCE_ELEMENT_TYPE_SHELL: | |
783 | if (s->data.exec == NULL) | |
784 | break; | |
785 | ignore_error = s->data.exec[0] == '-'; | |
786 | shell_retry: | |
787 | err = system(s->data.exec + (ignore_error ? 1 : 0)); | |
788 | if (WIFSIGNALED(err)) { | |
789 | err = -EINTR; | |
790 | } if (WIFEXITED(err)) { | |
791 | if (ignore_error == false && WEXITSTATUS(err) != 0) { | |
792 | uc_error("command '%s' failed (exit code %d)", s->data.exec, WEXITSTATUS(err)); | |
793 | err = -EINVAL; | |
794 | goto __fail; | |
795 | } | |
796 | } else if (err < 0) { | |
797 | if (errno == EAGAIN) | |
798 | goto shell_retry; | |
799 | err = -errno; | |
800 | goto __fail; | |
801 | } | |
429 | 802 | break; |
430 | 803 | case SEQUENCE_ELEMENT_TYPE_CMPT_SEQ: |
431 | 804 | /* Execute enable or disable sequence of a component |
440 | 813 | if (err < 0) |
441 | 814 | goto __fail; |
442 | 815 | break; |
816 | case SEQUENCE_ELEMENT_TYPE_CFGSAVE: | |
817 | err = execute_cfgsave(uc_mgr, s->data.cfgsave); | |
818 | if (err < 0) | |
819 | goto __fail; | |
820 | break; | |
443 | 821 | default: |
444 | 822 | uc_error("unknown sequence command %i", s->type); |
445 | 823 | break; |
593 | 971 | } |
594 | 972 | if (!list_empty(&uc_mgr->verb_list)) |
595 | 973 | return 0; |
974 | if (!list_empty(&uc_mgr->fixedboot_list)) | |
975 | return 0; | |
596 | 976 | if (!list_empty(&uc_mgr->boot_list)) |
597 | 977 | return 0; |
598 | 978 | return -ENXIO; |
636 | 1016 | * \return count of items on success, otherwise a negative error code |
637 | 1017 | */ |
638 | 1018 | static int get_list0(struct list_head *list, |
639 | const char **result[], | |
640 | unsigned long offset, | |
641 | unsigned long s1offset) | |
642 | { | |
643 | char **res; | |
644 | int cnt; | |
1019 | const char **result[], | |
1020 | unsigned long offset, | |
1021 | unsigned long s1offset) | |
1022 | { | |
1023 | char **res; | |
1024 | int cnt; | |
645 | 1025 | struct list_head *pos; |
646 | 1026 | char *ptr, *str1; |
647 | 1027 | |
648 | 1028 | cnt = alloc_str_list(list, 1, &res); |
649 | 1029 | if (cnt <= 0) { |
650 | 1030 | *result = NULL; |
651 | return cnt; | |
1031 | return cnt; | |
652 | 1032 | } |
653 | 1033 | *result = (const char **)res; |
654 | 1034 | list_for_each(pos, list) { |
655 | 1035 | ptr = list_entry_offset(pos, char, offset); |
656 | 1036 | str1 = *((char **)(ptr + s1offset)); |
657 | 1037 | if (str1 != NULL) { |
658 | *res = strdup(str1); | |
659 | if (*res == NULL) | |
660 | goto __fail; | |
661 | } else { | |
662 | *res = NULL; | |
663 | } | |
664 | res++; | |
1038 | *res = strdup(str1); | |
1039 | if (*res == NULL) | |
1040 | goto __fail; | |
1041 | } else { | |
1042 | *res = NULL; | |
1043 | } | |
1044 | res++; | |
665 | 1045 | } |
666 | 1046 | return cnt; |
667 | 1047 | __fail: |
668 | snd_use_case_free_list((const char **)res, cnt); | |
669 | return -ENOMEM; | |
1048 | snd_use_case_free_list(*result, cnt); | |
1049 | return -ENOMEM; | |
670 | 1050 | } |
671 | 1051 | |
672 | 1052 | #define get_list(list, result, type, member, s1) \ |
673 | 1053 | get_list0(list, result, \ |
674 | (unsigned long)(&((type *)0)->member), \ | |
1054 | (unsigned long)(&((type *)0)->member), \ | |
675 | 1055 | (unsigned long)(&((type *)0)->s1)) |
676 | 1056 | |
677 | 1057 | /** |
684 | 1064 | * \return count of items on success, otherwise a negative error code |
685 | 1065 | */ |
686 | 1066 | static int get_list20(struct list_head *list, |
687 | const char **result[], | |
688 | unsigned long offset, | |
689 | unsigned long s1offset, | |
690 | unsigned long s2offset) | |
691 | { | |
692 | char **res; | |
693 | int cnt; | |
1067 | const char **result[], | |
1068 | unsigned long offset, | |
1069 | unsigned long s1offset, | |
1070 | unsigned long s2offset) | |
1071 | { | |
1072 | char **res; | |
1073 | int cnt; | |
694 | 1074 | struct list_head *pos; |
695 | 1075 | char *ptr, *str1, *str2; |
696 | 1076 | |
697 | 1077 | cnt = alloc_str_list(list, 2, &res); |
698 | 1078 | if (cnt <= 0) { |
699 | 1079 | *result = NULL; |
700 | return cnt; | |
701 | } | |
702 | *result = (const char **)res; | |
1080 | return cnt; | |
1081 | } | |
1082 | *result = (const char **)res; | |
703 | 1083 | list_for_each(pos, list) { |
704 | 1084 | ptr = list_entry_offset(pos, char, offset); |
705 | 1085 | str1 = *((char **)(ptr + s1offset)); |
706 | 1086 | if (str1 != NULL) { |
707 | *res = strdup(str1); | |
708 | if (*res == NULL) | |
709 | goto __fail; | |
710 | } else { | |
711 | *res = NULL; | |
712 | } | |
713 | res++; | |
1087 | *res = strdup(str1); | |
1088 | if (*res == NULL) | |
1089 | goto __fail; | |
1090 | } else { | |
1091 | *res = NULL; | |
1092 | } | |
1093 | res++; | |
714 | 1094 | str2 = *((char **)(ptr + s2offset)); |
715 | 1095 | if (str2 != NULL) { |
716 | *res = strdup(str2); | |
717 | if (*res == NULL) | |
718 | goto __fail; | |
719 | } else { | |
720 | *res = NULL; | |
721 | } | |
722 | res++; | |
1096 | *res = strdup(str2); | |
1097 | if (*res == NULL) | |
1098 | goto __fail; | |
1099 | } else { | |
1100 | *res = NULL; | |
1101 | } | |
1102 | res++; | |
723 | 1103 | } |
724 | 1104 | return cnt; |
725 | 1105 | __fail: |
726 | snd_use_case_free_list((const char **)res, cnt); | |
727 | return -ENOMEM; | |
1106 | snd_use_case_free_list(*result, cnt); | |
1107 | return -ENOMEM; | |
728 | 1108 | } |
729 | 1109 | |
730 | 1110 | #define get_list2(list, result, type, member, s1, s2) \ |
731 | 1111 | get_list20(list, result, \ |
732 | (unsigned long)(&((type *)0)->member), \ | |
1112 | (unsigned long)(&((type *)0)->member), \ | |
733 | 1113 | (unsigned long)(&((type *)0)->s1), \ |
734 | 1114 | (unsigned long)(&((type *)0)->s2)) |
735 | 1115 | |
799 | 1179 | * \return structure on success, otherwise a NULL (not found) |
800 | 1180 | */ |
801 | 1181 | static inline struct use_case_device * |
802 | find_device(snd_use_case_mgr_t *uc_mgr, struct use_case_verb *verb, | |
1182 | find_device(snd_use_case_mgr_t *uc_mgr, struct use_case_verb *verb, | |
803 | 1183 | const char *device_name, int check_supported) |
804 | 1184 | { |
805 | 1185 | struct use_case_device *device; |
827 | 1207 | * \return structure on success, otherwise a NULL (not found) |
828 | 1208 | */ |
829 | 1209 | static struct use_case_modifier * |
830 | find_modifier(snd_use_case_mgr_t *uc_mgr, struct use_case_verb *verb, | |
1210 | find_modifier(snd_use_case_mgr_t *uc_mgr, struct use_case_verb *verb, | |
831 | 1211 | const char *modifier_name, int check_supported) |
832 | 1212 | { |
833 | 1213 | struct use_case_modifier *modifier; |
849 | 1229 | } |
850 | 1230 | |
851 | 1231 | long device_status(snd_use_case_mgr_t *uc_mgr, |
852 | const char *device_name) | |
853 | { | |
854 | struct use_case_device *dev; | |
855 | struct list_head *pos; | |
856 | ||
857 | list_for_each(pos, &uc_mgr->active_devices) { | |
858 | dev = list_entry(pos, struct use_case_device, active_list); | |
859 | if (strcmp(dev->name, device_name) == 0) | |
860 | return 1; | |
861 | } | |
862 | return 0; | |
1232 | const char *device_name) | |
1233 | { | |
1234 | struct use_case_device *dev; | |
1235 | struct list_head *pos; | |
1236 | ||
1237 | list_for_each(pos, &uc_mgr->active_devices) { | |
1238 | dev = list_entry(pos, struct use_case_device, active_list); | |
1239 | if (strcmp(dev->name, device_name) == 0) | |
1240 | return 1; | |
1241 | } | |
1242 | return 0; | |
863 | 1243 | } |
864 | 1244 | |
865 | 1245 | long modifier_status(snd_use_case_mgr_t *uc_mgr, |
866 | const char *modifier_name) | |
867 | { | |
868 | struct use_case_modifier *mod; | |
869 | struct list_head *pos; | |
870 | ||
871 | list_for_each(pos, &uc_mgr->active_modifiers) { | |
872 | mod = list_entry(pos, struct use_case_modifier, active_list); | |
873 | if (strcmp(mod->name, modifier_name) == 0) | |
874 | return 1; | |
875 | } | |
876 | return 0; | |
1246 | const char *modifier_name) | |
1247 | { | |
1248 | struct use_case_modifier *mod; | |
1249 | struct list_head *pos; | |
1250 | ||
1251 | list_for_each(pos, &uc_mgr->active_modifiers) { | |
1252 | mod = list_entry(pos, struct use_case_modifier, active_list); | |
1253 | if (strcmp(mod->name, modifier_name) == 0) | |
1254 | return 1; | |
1255 | } | |
1256 | return 0; | |
877 | 1257 | } |
878 | 1258 | |
879 | 1259 | /** |
955 | 1335 | struct list_head *seq; |
956 | 1336 | int err; |
957 | 1337 | |
958 | if (device_status(uc_mgr, device->name) == enable) | |
1338 | if (device_status(uc_mgr, device->name) == enable) | |
959 | 1339 | return 0; |
960 | 1340 | |
961 | 1341 | if (enable) { |
992 | 1372 | if (mgr == NULL) |
993 | 1373 | return -ENOMEM; |
994 | 1374 | INIT_LIST_HEAD(&mgr->verb_list); |
1375 | INIT_LIST_HEAD(&mgr->fixedboot_list); | |
995 | 1376 | INIT_LIST_HEAD(&mgr->boot_list); |
996 | 1377 | INIT_LIST_HEAD(&mgr->default_list); |
997 | 1378 | INIT_LIST_HEAD(&mgr->value_list); |
1001 | 1382 | INIT_LIST_HEAD(&mgr->variable_list); |
1002 | 1383 | pthread_mutex_init(&mgr->mutex, NULL); |
1003 | 1384 | |
1385 | err = uc_mgr_card_open(mgr); | |
1386 | if (err < 0) { | |
1387 | uc_mgr_free(mgr); | |
1388 | return err; | |
1389 | } | |
1390 | ||
1391 | err = snd_config_top(&mgr->local_config); | |
1392 | if (err < 0) | |
1393 | goto _err; | |
1394 | ||
1004 | 1395 | mgr->card_name = strdup(card_name); |
1005 | 1396 | if (mgr->card_name == NULL) { |
1006 | free(mgr); | |
1007 | return -ENOMEM; | |
1397 | err = -ENOMEM; | |
1398 | goto _err; | |
1008 | 1399 | } |
1009 | 1400 | |
1010 | 1401 | /* get info on use_cases and verify against card */ |
1025 | 1416 | return 0; |
1026 | 1417 | |
1027 | 1418 | _err: |
1419 | uc_mgr_card_close(mgr); | |
1028 | 1420 | uc_mgr_free(mgr); |
1029 | 1421 | return err; |
1030 | 1422 | } |
1063 | 1455 | */ |
1064 | 1456 | int snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr) |
1065 | 1457 | { |
1458 | uc_mgr_card_close(uc_mgr); | |
1066 | 1459 | uc_mgr_free(uc_mgr); |
1067 | 1460 | |
1068 | 1461 | return 0; |
1116 | 1509 | */ |
1117 | 1510 | int snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr) |
1118 | 1511 | { |
1119 | int err; | |
1512 | int err; | |
1120 | 1513 | |
1121 | 1514 | pthread_mutex_lock(&uc_mgr->mutex); |
1122 | 1515 | err = execute_sequence(uc_mgr, &uc_mgr->default_list, |
1135 | 1528 | */ |
1136 | 1529 | static int get_verb_list(snd_use_case_mgr_t *uc_mgr, const char **list[]) |
1137 | 1530 | { |
1138 | return get_list2(&uc_mgr->verb_list, list, | |
1139 | struct use_case_verb, list, | |
1140 | name, comment); | |
1531 | return get_list2(&uc_mgr->verb_list, list, | |
1532 | struct use_case_verb, list, | |
1533 | name, comment); | |
1141 | 1534 | } |
1142 | 1535 | |
1143 | 1536 | /** |
1147 | 1540 | * \return Number of list entries if success, otherwise a negative error code |
1148 | 1541 | */ |
1149 | 1542 | static int get_device_list(snd_use_case_mgr_t *uc_mgr, const char **list[], |
1150 | char *verbname) | |
1151 | { | |
1152 | struct use_case_verb *verb; | |
1153 | ||
1154 | if (verbname) { | |
1155 | verb = find_verb(uc_mgr, verbname); | |
1156 | } else { | |
1157 | verb = uc_mgr->active_verb; | |
1158 | } | |
1159 | if (verb == NULL) | |
1160 | return -ENOENT; | |
1161 | return get_list2(&verb->device_list, list, | |
1162 | struct use_case_device, list, | |
1163 | name, comment); | |
1543 | char *verbname) | |
1544 | { | |
1545 | struct use_case_verb *verb; | |
1546 | ||
1547 | if (verbname) { | |
1548 | verb = find_verb(uc_mgr, verbname); | |
1549 | } else { | |
1550 | verb = uc_mgr->active_verb; | |
1551 | } | |
1552 | if (verb == NULL) | |
1553 | return -ENOENT; | |
1554 | return get_list2(&verb->device_list, list, | |
1555 | struct use_case_device, list, | |
1556 | name, comment); | |
1164 | 1557 | } |
1165 | 1558 | |
1166 | 1559 | /** |
1170 | 1563 | * \return Number of list entries if success, otherwise a negative error code |
1171 | 1564 | */ |
1172 | 1565 | static int get_modifier_list(snd_use_case_mgr_t *uc_mgr, const char **list[], |
1173 | char *verbname) | |
1174 | { | |
1175 | struct use_case_verb *verb; | |
1176 | ||
1177 | if (verbname) { | |
1178 | verb = find_verb(uc_mgr, verbname); | |
1179 | } else { | |
1180 | verb = uc_mgr->active_verb; | |
1181 | } | |
1182 | if (verb == NULL) | |
1183 | return -ENOENT; | |
1184 | return get_list2(&verb->modifier_list, list, | |
1185 | struct use_case_modifier, list, | |
1186 | name, comment); | |
1566 | char *verbname) | |
1567 | { | |
1568 | struct use_case_verb *verb; | |
1569 | if (verbname) { | |
1570 | verb = find_verb(uc_mgr, verbname); | |
1571 | } else { | |
1572 | verb = uc_mgr->active_verb; | |
1573 | } | |
1574 | if (verb == NULL) | |
1575 | return -ENOENT; | |
1576 | return get_list2(&verb->modifier_list, list, | |
1577 | struct use_case_modifier, list, | |
1578 | name, comment); | |
1187 | 1579 | } |
1188 | 1580 | |
1189 | 1581 | /** |
1370 | 1762 | * \param source Source list with ucm_value structures |
1371 | 1763 | */ |
1372 | 1764 | static int add_values(struct list_head *list, |
1373 | const char *identifier, | |
1374 | struct list_head *source) | |
1765 | const char *identifier, | |
1766 | struct list_head *source) | |
1375 | 1767 | { |
1376 | 1768 | struct ucm_value *v; |
1377 | 1769 | struct list_head *pos; |
1378 | 1770 | int err; |
1379 | ||
1771 | ||
1380 | 1772 | list_for_each(pos, source) { |
1381 | 1773 | v = list_entry(pos, struct ucm_value, list); |
1382 | 1774 | if (check_identifier(identifier, v->name)) { |
1471 | 1863 | * \return Number of list entries if success, otherwise a negative error code |
1472 | 1864 | */ |
1473 | 1865 | static int get_value_list(snd_use_case_mgr_t *uc_mgr, |
1474 | const char *identifier, | |
1475 | const char **list[], | |
1476 | char *verbname) | |
1866 | const char *identifier, | |
1867 | const char **list[], | |
1868 | char *verbname) | |
1477 | 1869 | { |
1478 | 1870 | struct list_head mylist, *pos; |
1479 | struct use_case_verb *verb; | |
1480 | struct use_case_device *dev; | |
1481 | struct use_case_modifier *mod; | |
1482 | char **res; | |
1483 | int err; | |
1484 | ||
1485 | if (verbname) { | |
1486 | verb = find_verb(uc_mgr, verbname); | |
1487 | } else { | |
1488 | verb = uc_mgr->active_verb; | |
1489 | } | |
1490 | if (verb == NULL) | |
1491 | return -ENOENT; | |
1492 | INIT_LIST_HEAD(&mylist); | |
1871 | struct use_case_verb *verb; | |
1872 | struct use_case_device *dev; | |
1873 | struct use_case_modifier *mod; | |
1874 | char **res; | |
1875 | int err; | |
1876 | ||
1877 | if (verbname) { | |
1878 | verb = find_verb(uc_mgr, verbname); | |
1879 | } else { | |
1880 | verb = uc_mgr->active_verb; | |
1881 | } | |
1882 | if (verb == NULL) | |
1883 | return -ENOENT; | |
1884 | INIT_LIST_HEAD(&mylist); | |
1493 | 1885 | err = add_values(&mylist, identifier, &uc_mgr->value_list); |
1494 | 1886 | if (err < 0) |
1495 | 1887 | goto __fail; |
1496 | err = add_values(&mylist, identifier, &verb->value_list); | |
1497 | if (err < 0) | |
1498 | goto __fail; | |
1499 | list_for_each(pos, &verb->device_list) { | |
1500 | dev = list_entry(pos, struct use_case_device, list); | |
1501 | err = add_values(&mylist, identifier, &dev->value_list); | |
1502 | if (err < 0) | |
1503 | goto __fail; | |
1504 | } | |
1505 | list_for_each(pos, &verb->modifier_list) { | |
1506 | mod = list_entry(pos, struct use_case_modifier, list); | |
1507 | err = add_values(&mylist, identifier, &mod->value_list); | |
1508 | if (err < 0) | |
1509 | goto __fail; | |
1510 | } | |
1888 | err = add_values(&mylist, identifier, &verb->value_list); | |
1889 | if (err < 0) | |
1890 | goto __fail; | |
1891 | list_for_each(pos, &verb->device_list) { | |
1892 | dev = list_entry(pos, struct use_case_device, list); | |
1893 | err = add_values(&mylist, identifier, &dev->value_list); | |
1894 | if (err < 0) | |
1895 | goto __fail; | |
1896 | } | |
1897 | list_for_each(pos, &verb->modifier_list) { | |
1898 | mod = list_entry(pos, struct use_case_modifier, list); | |
1899 | err = add_values(&mylist, identifier, &mod->value_list); | |
1900 | if (err < 0) | |
1901 | goto __fail; | |
1902 | } | |
1511 | 1903 | err = myvalue_to_str_list(&mylist, &res); |
1512 | 1904 | if (err > 0) |
1513 | *list = (const char **)res; | |
1905 | *list = (const char **)res; | |
1514 | 1906 | else if (err == 0) |
1515 | 1907 | *list = NULL; |
1516 | 1908 | __fail: |
1517 | 1909 | myvalue_list_free(&mylist); |
1518 | return err; | |
1910 | return err; | |
1519 | 1911 | } |
1520 | 1912 | |
1521 | 1913 | /** |
1525 | 1917 | * \return Number of list entries if success, otherwise a negative error code |
1526 | 1918 | */ |
1527 | 1919 | static int get_enabled_device_list(snd_use_case_mgr_t *uc_mgr, |
1528 | const char **list[]) | |
1529 | { | |
1530 | if (uc_mgr->active_verb == NULL) | |
1531 | return -EINVAL; | |
1532 | return get_list(&uc_mgr->active_devices, list, | |
1533 | struct use_case_device, active_list, | |
1534 | name); | |
1920 | const char **list[]) | |
1921 | { | |
1922 | if (uc_mgr->active_verb == NULL) | |
1923 | return -EINVAL; | |
1924 | return get_list(&uc_mgr->active_devices, list, | |
1925 | struct use_case_device, active_list, | |
1926 | name); | |
1535 | 1927 | } |
1536 | 1928 | |
1537 | 1929 | /** |
1541 | 1933 | * \return Number of list entries if success, otherwise a negative error code |
1542 | 1934 | */ |
1543 | 1935 | static int get_enabled_modifier_list(snd_use_case_mgr_t *uc_mgr, |
1544 | const char **list[]) | |
1545 | { | |
1546 | if (uc_mgr->active_verb == NULL) | |
1547 | return -EINVAL; | |
1548 | return get_list(&uc_mgr->active_modifiers, list, | |
1549 | struct use_case_modifier, active_list, | |
1550 | name); | |
1936 | const char **list[]) | |
1937 | { | |
1938 | if (uc_mgr->active_verb == NULL) | |
1939 | return -EINVAL; | |
1940 | return get_list(&uc_mgr->active_modifiers, list, | |
1941 | struct use_case_modifier, active_list, | |
1942 | name); | |
1551 | 1943 | } |
1552 | 1944 | |
1553 | 1945 | /** |
1569 | 1961 | pthread_mutex_lock(&uc_mgr->mutex); |
1570 | 1962 | if (strcmp(identifier, "_verbs") == 0) |
1571 | 1963 | err = get_verb_list(uc_mgr, list); |
1572 | else if (strcmp(identifier, "_enadevs") == 0) | |
1573 | err = get_enabled_device_list(uc_mgr, list); | |
1574 | else if (strcmp(identifier, "_enamods") == 0) | |
1575 | err = get_enabled_modifier_list(uc_mgr, list); | |
1576 | else { | |
1577 | str1 = strchr(identifier, '/'); | |
1578 | if (str1) { | |
1579 | str = strdup(str1 + 1); | |
1580 | if (str == NULL) { | |
1581 | err = -ENOMEM; | |
1582 | goto __end; | |
1583 | } | |
1584 | } else { | |
1585 | str = NULL; | |
1586 | } | |
1964 | else if (strcmp(identifier, "_enadevs") == 0) | |
1965 | err = get_enabled_device_list(uc_mgr, list); | |
1966 | else if (strcmp(identifier, "_enamods") == 0) | |
1967 | err = get_enabled_modifier_list(uc_mgr, list); | |
1968 | else { | |
1969 | str1 = strchr(identifier, '/'); | |
1970 | if (str1) { | |
1971 | str = strdup(str1 + 1); | |
1972 | if (str == NULL) { | |
1973 | err = -ENOMEM; | |
1974 | goto __end; | |
1975 | } | |
1976 | } else { | |
1977 | str = NULL; | |
1978 | } | |
1587 | 1979 | if (check_identifier(identifier, "_devices")) |
1588 | 1980 | err = get_device_list(uc_mgr, list, str); |
1589 | else if (check_identifier(identifier, "_modifiers")) | |
1981 | else if (check_identifier(identifier, "_modifiers")) | |
1590 | 1982 | err = get_modifier_list(uc_mgr, list, str); |
1591 | 1983 | else if (check_identifier(identifier, "_identifiers")) |
1592 | 1984 | err = get_identifiers_list(uc_mgr, list, str); |
1609 | 2001 | static int get_value1(snd_use_case_mgr_t *uc_mgr, char **value, |
1610 | 2002 | struct list_head *value_list, const char *identifier) |
1611 | 2003 | { |
1612 | struct ucm_value *val; | |
1613 | struct list_head *pos; | |
1614 | ||
2004 | struct ucm_value *val; | |
2005 | struct list_head *pos; | |
2006 | int err; | |
2007 | ||
1615 | 2008 | if (!value_list) |
1616 | 2009 | return -ENOENT; |
1617 | 2010 | |
1618 | list_for_each(pos, value_list) { | |
2011 | list_for_each(pos, value_list) { | |
1619 | 2012 | val = list_entry(pos, struct ucm_value, list); |
1620 | 2013 | if (check_identifier(identifier, val->name)) { |
1621 | 2014 | if (uc_mgr->conf_format < 2) { |
1624 | 2017 | return -ENOMEM; |
1625 | 2018 | return 0; |
1626 | 2019 | } |
1627 | return uc_mgr_get_substituted_value(uc_mgr, value, val->data); | |
1628 | } | |
1629 | } | |
1630 | return -ENOENT; | |
2020 | err = uc_mgr_get_substituted_value(uc_mgr, value, val->data); | |
2021 | if (err < 0) | |
2022 | return err; | |
2023 | return rewrite_device_value(uc_mgr, val->name, value); | |
2024 | } | |
2025 | } | |
2026 | return -ENOENT; | |
1631 | 2027 | } |
1632 | 2028 | |
1633 | 2029 | static int get_value3(snd_use_case_mgr_t *uc_mgr, |
1717 | 2113 | return err; |
1718 | 2114 | |
1719 | 2115 | return -ENOENT; |
2116 | } | |
2117 | ||
2118 | /** | |
2119 | * \brief Get private alsa-lib configuration (ASCII) | |
2120 | * \param uc_mgr Use case manager | |
2121 | * \param str Returned value string | |
2122 | * \return Zero on success (value is filled), otherwise a negative error code | |
2123 | */ | |
2124 | static int get_alibcfg(snd_use_case_mgr_t *uc_mgr, char **str) | |
2125 | { | |
2126 | snd_output_t *out; | |
2127 | size_t size; | |
2128 | int err; | |
2129 | ||
2130 | err = snd_output_buffer_open(&out); | |
2131 | if (err < 0) | |
2132 | return err; | |
2133 | err = snd_config_save(uc_mgr->local_config, out); | |
2134 | if (err >= 0) { | |
2135 | size = snd_output_buffer_steal(out, str); | |
2136 | if (*str) | |
2137 | (*str)[size] = '\0'; | |
2138 | } | |
2139 | snd_output_close(out); | |
2140 | return 0; | |
2141 | } | |
2142 | ||
2143 | /** | |
2144 | * \brief Get device prefix for private alsa-lib configuration | |
2145 | * \param uc_mgr Use case manager | |
2146 | * \param str Returned value string | |
2147 | * \return Zero on success (value is filled), otherwise a negative error code | |
2148 | */ | |
2149 | static int get_alibpref(snd_use_case_mgr_t *uc_mgr, char **str) | |
2150 | { | |
2151 | const size_t l = 10; | |
2152 | char *s; | |
2153 | ||
2154 | s = malloc(l); | |
2155 | if (s == NULL) | |
2156 | return -ENOMEM; | |
2157 | snprintf(s, l, "_ucm%04X.", uc_mgr->ucm_card_number); | |
2158 | *str = s; | |
2159 | return 0; | |
1720 | 2160 | } |
1721 | 2161 | |
1722 | 2162 | /** |
1736 | 2176 | const char *slash1, *slash2, *mod_dev_after; |
1737 | 2177 | const char *ident, *mod_dev, *verb; |
1738 | 2178 | int exact = 0; |
1739 | int err; | |
2179 | int err; | |
1740 | 2180 | |
1741 | 2181 | pthread_mutex_lock(&uc_mgr->mutex); |
1742 | 2182 | if (identifier == NULL) { |
1743 | *value = strdup(uc_mgr->card_name); | |
1744 | if (*value == NULL) { | |
1745 | err = -ENOMEM; | |
1746 | goto __end; | |
1747 | } | |
1748 | err = 0; | |
1749 | } else if (strcmp(identifier, "_verb") == 0) { | |
1750 | if (uc_mgr->active_verb == NULL) { | |
1751 | err = -ENOENT; | |
2183 | *value = strdup(uc_mgr->card_name); | |
2184 | if (*value == NULL) { | |
2185 | err = -ENOMEM; | |
1752 | 2186 | goto __end; |
1753 | 2187 | } |
1754 | *value = strdup(uc_mgr->active_verb->name); | |
1755 | if (*value == NULL) { | |
1756 | err = -ENOMEM; | |
1757 | goto __end; | |
1758 | } | |
1759 | err = 0; | |
2188 | err = 0; | |
2189 | } else if (strcmp(identifier, "_verb") == 0) { | |
2190 | if (uc_mgr->active_verb == NULL) { | |
2191 | err = -ENOENT; | |
2192 | goto __end; | |
2193 | } | |
2194 | *value = strdup(uc_mgr->active_verb->name); | |
2195 | if (*value == NULL) { | |
2196 | err = -ENOMEM; | |
2197 | goto __end; | |
2198 | } | |
2199 | err = 0; | |
1760 | 2200 | } else if (strcmp(identifier, "_file") == 0) { |
1761 | 2201 | /* get the conf file name of the opened card */ |
1762 | 2202 | if ((uc_mgr->card_name == NULL) || |
1772 | 2212 | } |
1773 | 2213 | err = 0; |
1774 | 2214 | |
2215 | } else if (strcmp(identifier, "_alibcfg") == 0) { | |
2216 | err = get_alibcfg(uc_mgr, (char **)value); | |
2217 | } else if (strcmp(identifier, "_alibpref") == 0) { | |
2218 | err = get_alibpref(uc_mgr, (char **)value); | |
1775 | 2219 | } else if (identifier[0] == '_') { |
1776 | 2220 | err = -ENOENT; |
1777 | goto __end; | |
1778 | } else { | |
2221 | } else { | |
1779 | 2222 | if (identifier[0] == '=') { |
1780 | 2223 | exact = 1; |
1781 | 2224 | identifier++; |
1808 | 2251 | } |
1809 | 2252 | |
1810 | 2253 | err = get_value(uc_mgr, ident, (char **)value, mod_dev, verb, |
1811 | exact); | |
2254 | exact); | |
1812 | 2255 | if (ident != identifier) |
1813 | 2256 | free((void *)ident); |
1814 | 2257 | if (mod_dev) |
1815 | 2258 | free((void *)mod_dev); |
1816 | } | |
2259 | } | |
1817 | 2260 | __end: |
1818 | 2261 | pthread_mutex_unlock(&uc_mgr->mutex); |
1819 | return err; | |
2262 | return err; | |
1820 | 2263 | } |
1821 | 2264 | |
1822 | 2265 | |
1830 | 2273 | const char *identifier, |
1831 | 2274 | long *value) |
1832 | 2275 | { |
1833 | char *str, *str1; | |
1834 | long err; | |
2276 | char *str, *str1; | |
2277 | long err; | |
1835 | 2278 | |
1836 | 2279 | pthread_mutex_lock(&uc_mgr->mutex); |
1837 | if (0) { | |
1838 | /* nothing here - prepared for fixed identifiers */ | |
1839 | } else { | |
1840 | str1 = strchr(identifier, '/'); | |
1841 | if (str1) { | |
1842 | str = strdup(str1 + 1); | |
1843 | if (str == NULL) { | |
1844 | err = -ENOMEM; | |
1845 | goto __end; | |
1846 | } | |
1847 | } else { | |
1848 | str = NULL; | |
1849 | } | |
1850 | if (check_identifier(identifier, "_devstatus")) { | |
2280 | if (0) { | |
2281 | /* nothing here - prepared for fixed identifiers */ | |
2282 | } else { | |
2283 | str1 = strchr(identifier, '/'); | |
2284 | if (str1) { | |
2285 | str = strdup(str1 + 1); | |
2286 | if (str == NULL) { | |
2287 | err = -ENOMEM; | |
2288 | goto __end; | |
2289 | } | |
2290 | } else { | |
2291 | str = NULL; | |
2292 | } | |
2293 | if (check_identifier(identifier, "_devstatus")) { | |
1851 | 2294 | if (!str) { |
1852 | 2295 | err = -EINVAL; |
1853 | 2296 | goto __end; |
1854 | 2297 | } |
1855 | err = device_status(uc_mgr, str); | |
2298 | err = device_status(uc_mgr, str); | |
1856 | 2299 | if (err >= 0) { |
1857 | 2300 | *value = err; |
1858 | 2301 | err = 0; |
1862 | 2305 | err = -EINVAL; |
1863 | 2306 | goto __end; |
1864 | 2307 | } |
1865 | err = modifier_status(uc_mgr, str); | |
2308 | err = modifier_status(uc_mgr, str); | |
1866 | 2309 | if (err >= 0) { |
1867 | 2310 | *value = err; |
1868 | 2311 | err = 0; |
1876 | 2319 | err = -ENOENT; |
1877 | 2320 | #endif |
1878 | 2321 | } else |
1879 | err = -ENOENT; | |
1880 | if (str) | |
1881 | free(str); | |
1882 | } | |
2322 | err = -ENOENT; | |
2323 | if (str) | |
2324 | free(str); | |
2325 | } | |
1883 | 2326 | __end: |
1884 | 2327 | pthread_mutex_unlock(&uc_mgr->mutex); |
1885 | return err; | |
2328 | return err; | |
2329 | } | |
2330 | ||
2331 | static int set_fixedboot_user(snd_use_case_mgr_t *uc_mgr, | |
2332 | const char *value) | |
2333 | { | |
2334 | int err; | |
2335 | ||
2336 | if (value != NULL && *value) { | |
2337 | uc_error("error: wrong value for _fboot (%s)", value); | |
2338 | return -EINVAL; | |
2339 | } | |
2340 | if (list_empty(&uc_mgr->fixedboot_list)) | |
2341 | return -ENOENT; | |
2342 | err = execute_sequence(uc_mgr, &uc_mgr->fixedboot_list, | |
2343 | &uc_mgr->value_list, NULL, NULL); | |
2344 | if (err < 0) { | |
2345 | uc_error("Unable to execute force boot sequence"); | |
2346 | return err; | |
2347 | } | |
2348 | return err; | |
1886 | 2349 | } |
1887 | 2350 | |
1888 | 2351 | static int set_boot_user(snd_use_case_mgr_t *uc_mgr, |
1894 | 2357 | uc_error("error: wrong value for _boot (%s)", value); |
1895 | 2358 | return -EINVAL; |
1896 | 2359 | } |
2360 | if (list_empty(&uc_mgr->boot_list)) | |
2361 | return -ENOENT; | |
1897 | 2362 | err = execute_sequence(uc_mgr, &uc_mgr->boot_list, |
1898 | 2363 | &uc_mgr->value_list, NULL, NULL); |
1899 | 2364 | if (err < 0) { |
1914 | 2379 | } |
1915 | 2380 | |
1916 | 2381 | static int handle_transition_verb(snd_use_case_mgr_t *uc_mgr, |
1917 | struct use_case_verb *new_verb) | |
1918 | { | |
1919 | struct list_head *pos; | |
1920 | struct transition_sequence *trans; | |
1921 | int err; | |
1922 | ||
1923 | list_for_each(pos, &uc_mgr->active_verb->transition_list) { | |
1924 | trans = list_entry(pos, struct transition_sequence, list); | |
1925 | if (strcmp(trans->name, new_verb->name) == 0) { | |
1926 | err = execute_sequence(uc_mgr, &trans->transition_list, | |
2382 | struct use_case_verb *new_verb) | |
2383 | { | |
2384 | struct list_head *pos; | |
2385 | struct transition_sequence *trans; | |
2386 | int err; | |
2387 | ||
2388 | list_for_each(pos, &uc_mgr->active_verb->transition_list) { | |
2389 | trans = list_entry(pos, struct transition_sequence, list); | |
2390 | if (strcmp(trans->name, new_verb->name) == 0) { | |
2391 | err = execute_sequence(uc_mgr, &trans->transition_list, | |
1927 | 2392 | &uc_mgr->active_verb->value_list, |
1928 | 2393 | &uc_mgr->value_list, |
1929 | 2394 | NULL); |
1930 | if (err >= 0) | |
1931 | return 1; | |
1932 | return err; | |
1933 | } | |
1934 | } | |
1935 | return 0; | |
2395 | if (err >= 0) | |
2396 | return 1; | |
2397 | return err; | |
2398 | } | |
2399 | } | |
2400 | return 0; | |
1936 | 2401 | } |
1937 | 2402 | |
1938 | 2403 | static int set_verb_user(snd_use_case_mgr_t *uc_mgr, |
1939 | const char *verb_name) | |
1940 | { | |
1941 | struct use_case_verb *verb; | |
1942 | int err = 0; | |
1943 | ||
1944 | if (uc_mgr->active_verb && | |
1945 | strcmp(uc_mgr->active_verb->name, verb_name) == 0) | |
1946 | return 0; | |
1947 | if (strcmp(verb_name, SND_USE_CASE_VERB_INACTIVE) != 0) { | |
1948 | verb = find_verb(uc_mgr, verb_name); | |
1949 | if (verb == NULL) | |
1950 | return -ENOENT; | |
1951 | } else { | |
1952 | verb = NULL; | |
1953 | } | |
1954 | if (uc_mgr->active_verb) { | |
1955 | err = handle_transition_verb(uc_mgr, verb); | |
1956 | if (err == 0) { | |
1957 | err = dismantle_use_case(uc_mgr); | |
1958 | if (err < 0) | |
1959 | return err; | |
1960 | } else if (err == 1) { | |
1961 | uc_mgr->active_verb = verb; | |
1962 | verb = NULL; | |
1963 | } else { | |
1964 | verb = NULL; /* show error */ | |
1965 | } | |
1966 | } | |
1967 | if (verb) { | |
1968 | err = set_verb(uc_mgr, verb, 1); | |
1969 | if (err < 0) | |
1970 | uc_error("error: failed to initialize new use case: %s", | |
1971 | verb_name); | |
1972 | } | |
1973 | return err; | |
2404 | const char *verb_name) | |
2405 | { | |
2406 | struct use_case_verb *verb; | |
2407 | int err = 0; | |
2408 | ||
2409 | if (uc_mgr->active_verb && | |
2410 | strcmp(uc_mgr->active_verb->name, verb_name) == 0) | |
2411 | return 0; | |
2412 | if (strcmp(verb_name, SND_USE_CASE_VERB_INACTIVE) != 0) { | |
2413 | verb = find_verb(uc_mgr, verb_name); | |
2414 | if (verb == NULL) | |
2415 | return -ENOENT; | |
2416 | } else { | |
2417 | verb = NULL; | |
2418 | } | |
2419 | if (uc_mgr->active_verb) { | |
2420 | err = handle_transition_verb(uc_mgr, verb); | |
2421 | if (err == 0) { | |
2422 | err = dismantle_use_case(uc_mgr); | |
2423 | if (err < 0) | |
2424 | return err; | |
2425 | } else if (err == 1) { | |
2426 | uc_mgr->active_verb = verb; | |
2427 | verb = NULL; | |
2428 | } else { | |
2429 | verb = NULL; /* show error */ | |
2430 | } | |
2431 | } | |
2432 | if (verb) { | |
2433 | err = set_verb(uc_mgr, verb, 1); | |
2434 | if (err < 0) | |
2435 | uc_error("error: failed to initialize new use case: %s", | |
2436 | verb_name); | |
2437 | } | |
2438 | return err; | |
1974 | 2439 | } |
1975 | 2440 | |
1976 | 2441 | |
1977 | 2442 | static int set_device_user(snd_use_case_mgr_t *uc_mgr, |
1978 | const char *device_name, | |
1979 | int enable) | |
1980 | { | |
1981 | struct use_case_device *device; | |
1982 | ||
1983 | if (uc_mgr->active_verb == NULL) | |
1984 | return -ENOENT; | |
1985 | device = find_device(uc_mgr, uc_mgr->active_verb, device_name, 1); | |
1986 | if (device == NULL) | |
1987 | return -ENOENT; | |
1988 | return set_device(uc_mgr, device, enable); | |
2443 | const char *device_name, | |
2444 | int enable) | |
2445 | { | |
2446 | struct use_case_device *device; | |
2447 | ||
2448 | if (uc_mgr->active_verb == NULL) | |
2449 | return -ENOENT; | |
2450 | device = find_device(uc_mgr, uc_mgr->active_verb, device_name, 1); | |
2451 | if (device == NULL) | |
2452 | return -ENOENT; | |
2453 | return set_device(uc_mgr, device, enable); | |
1989 | 2454 | } |
1990 | 2455 | |
1991 | 2456 | static int set_modifier_user(snd_use_case_mgr_t *uc_mgr, |
1992 | const char *modifier_name, | |
1993 | int enable) | |
1994 | { | |
1995 | struct use_case_modifier *modifier; | |
1996 | ||
1997 | if (uc_mgr->active_verb == NULL) | |
1998 | return -ENOENT; | |
1999 | ||
2000 | modifier = find_modifier(uc_mgr, uc_mgr->active_verb, modifier_name, 1); | |
2001 | if (modifier == NULL) | |
2002 | return -ENOENT; | |
2003 | return set_modifier(uc_mgr, modifier, enable); | |
2457 | const char *modifier_name, | |
2458 | int enable) | |
2459 | { | |
2460 | struct use_case_modifier *modifier; | |
2461 | ||
2462 | if (uc_mgr->active_verb == NULL) | |
2463 | return -ENOENT; | |
2464 | ||
2465 | modifier = find_modifier(uc_mgr, uc_mgr->active_verb, modifier_name, 1); | |
2466 | if (modifier == NULL) | |
2467 | return -ENOENT; | |
2468 | return set_modifier(uc_mgr, modifier, enable); | |
2004 | 2469 | } |
2005 | 2470 | |
2006 | 2471 | static int switch_device(snd_use_case_mgr_t *uc_mgr, |
2007 | const char *old_device, | |
2008 | const char *new_device) | |
2009 | { | |
2010 | struct use_case_device *xold, *xnew; | |
2011 | struct transition_sequence *trans; | |
2012 | struct list_head *pos; | |
2013 | int err, seq_found = 0; | |
2014 | ||
2015 | if (uc_mgr->active_verb == NULL) | |
2016 | return -ENOENT; | |
2017 | if (device_status(uc_mgr, old_device) == 0) { | |
2018 | uc_error("error: device %s not enabled", old_device); | |
2019 | return -EINVAL; | |
2020 | } | |
2021 | if (device_status(uc_mgr, new_device) != 0) { | |
2022 | uc_error("error: device %s already enabled", new_device); | |
2023 | return -EINVAL; | |
2024 | } | |
2025 | xold = find_device(uc_mgr, uc_mgr->active_verb, old_device, 1); | |
2026 | if (xold == NULL) | |
2027 | return -ENOENT; | |
2028 | list_del(&xold->active_list); | |
2029 | xnew = find_device(uc_mgr, uc_mgr->active_verb, new_device, 1); | |
2030 | list_add_tail(&xold->active_list, &uc_mgr->active_devices); | |
2031 | if (xnew == NULL) | |
2032 | return -ENOENT; | |
2033 | err = 0; | |
2034 | list_for_each(pos, &xold->transition_list) { | |
2035 | trans = list_entry(pos, struct transition_sequence, list); | |
2036 | if (strcmp(trans->name, new_device) == 0) { | |
2037 | err = execute_sequence(uc_mgr, &trans->transition_list, | |
2472 | const char *old_device, | |
2473 | const char *new_device) | |
2474 | { | |
2475 | struct use_case_device *xold, *xnew; | |
2476 | struct transition_sequence *trans; | |
2477 | struct list_head *pos; | |
2478 | int err, seq_found = 0; | |
2479 | ||
2480 | if (uc_mgr->active_verb == NULL) | |
2481 | return -ENOENT; | |
2482 | if (device_status(uc_mgr, old_device) == 0) { | |
2483 | uc_error("error: device %s not enabled", old_device); | |
2484 | return -EINVAL; | |
2485 | } | |
2486 | if (device_status(uc_mgr, new_device) != 0) { | |
2487 | uc_error("error: device %s already enabled", new_device); | |
2488 | return -EINVAL; | |
2489 | } | |
2490 | xold = find_device(uc_mgr, uc_mgr->active_verb, old_device, 1); | |
2491 | if (xold == NULL) | |
2492 | return -ENOENT; | |
2493 | list_del(&xold->active_list); | |
2494 | xnew = find_device(uc_mgr, uc_mgr->active_verb, new_device, 1); | |
2495 | list_add_tail(&xold->active_list, &uc_mgr->active_devices); | |
2496 | if (xnew == NULL) | |
2497 | return -ENOENT; | |
2498 | err = 0; | |
2499 | list_for_each(pos, &xold->transition_list) { | |
2500 | trans = list_entry(pos, struct transition_sequence, list); | |
2501 | if (strcmp(trans->name, new_device) == 0) { | |
2502 | err = execute_sequence(uc_mgr, &trans->transition_list, | |
2038 | 2503 | &xold->value_list, |
2039 | 2504 | &uc_mgr->active_verb->value_list, |
2040 | 2505 | &uc_mgr->value_list); |
2041 | if (err >= 0) { | |
2042 | list_del(&xold->active_list); | |
2043 | list_add_tail(&xnew->active_list, &uc_mgr->active_devices); | |
2044 | } | |
2045 | seq_found = 1; | |
2046 | break; | |
2047 | } | |
2048 | } | |
2049 | if (!seq_found) { | |
2050 | err = set_device(uc_mgr, xold, 0); | |
2051 | if (err < 0) | |
2052 | return err; | |
2053 | err = set_device(uc_mgr, xnew, 1); | |
2054 | if (err < 0) | |
2055 | return err; | |
2056 | } | |
2057 | return err; | |
2506 | if (err >= 0) { | |
2507 | list_del(&xold->active_list); | |
2508 | list_add_tail(&xnew->active_list, &uc_mgr->active_devices); | |
2509 | } | |
2510 | seq_found = 1; | |
2511 | break; | |
2512 | } | |
2513 | } | |
2514 | if (!seq_found) { | |
2515 | err = set_device(uc_mgr, xold, 0); | |
2516 | if (err < 0) | |
2517 | return err; | |
2518 | err = set_device(uc_mgr, xnew, 1); | |
2519 | if (err < 0) | |
2520 | return err; | |
2521 | } | |
2522 | return err; | |
2058 | 2523 | } |
2059 | 2524 | |
2060 | 2525 | static int switch_modifier(snd_use_case_mgr_t *uc_mgr, |
2061 | const char *old_modifier, | |
2062 | const char *new_modifier) | |
2063 | { | |
2064 | struct use_case_modifier *xold, *xnew; | |
2065 | struct transition_sequence *trans; | |
2066 | struct list_head *pos; | |
2067 | int err, seq_found = 0; | |
2068 | ||
2069 | if (uc_mgr->active_verb == NULL) | |
2070 | return -ENOENT; | |
2071 | if (modifier_status(uc_mgr, old_modifier) == 0) { | |
2072 | uc_error("error: modifier %s not enabled", old_modifier); | |
2073 | return -EINVAL; | |
2074 | } | |
2075 | if (modifier_status(uc_mgr, new_modifier) != 0) { | |
2076 | uc_error("error: modifier %s already enabled", new_modifier); | |
2077 | return -EINVAL; | |
2078 | } | |
2079 | xold = find_modifier(uc_mgr, uc_mgr->active_verb, old_modifier, 1); | |
2080 | if (xold == NULL) | |
2081 | return -ENOENT; | |
2082 | xnew = find_modifier(uc_mgr, uc_mgr->active_verb, new_modifier, 1); | |
2083 | if (xnew == NULL) | |
2084 | return -ENOENT; | |
2085 | err = 0; | |
2086 | list_for_each(pos, &xold->transition_list) { | |
2087 | trans = list_entry(pos, struct transition_sequence, list); | |
2088 | if (strcmp(trans->name, new_modifier) == 0) { | |
2089 | err = execute_sequence(uc_mgr, &trans->transition_list, | |
2526 | const char *old_modifier, | |
2527 | const char *new_modifier) | |
2528 | { | |
2529 | struct use_case_modifier *xold, *xnew; | |
2530 | struct transition_sequence *trans; | |
2531 | struct list_head *pos; | |
2532 | int err, seq_found = 0; | |
2533 | ||
2534 | if (uc_mgr->active_verb == NULL) | |
2535 | return -ENOENT; | |
2536 | if (modifier_status(uc_mgr, old_modifier) == 0) { | |
2537 | uc_error("error: modifier %s not enabled", old_modifier); | |
2538 | return -EINVAL; | |
2539 | } | |
2540 | if (modifier_status(uc_mgr, new_modifier) != 0) { | |
2541 | uc_error("error: modifier %s already enabled", new_modifier); | |
2542 | return -EINVAL; | |
2543 | } | |
2544 | xold = find_modifier(uc_mgr, uc_mgr->active_verb, old_modifier, 1); | |
2545 | if (xold == NULL) | |
2546 | return -ENOENT; | |
2547 | xnew = find_modifier(uc_mgr, uc_mgr->active_verb, new_modifier, 1); | |
2548 | if (xnew == NULL) | |
2549 | return -ENOENT; | |
2550 | err = 0; | |
2551 | list_for_each(pos, &xold->transition_list) { | |
2552 | trans = list_entry(pos, struct transition_sequence, list); | |
2553 | if (strcmp(trans->name, new_modifier) == 0) { | |
2554 | err = execute_sequence(uc_mgr, &trans->transition_list, | |
2090 | 2555 | &xold->value_list, |
2091 | 2556 | &uc_mgr->active_verb->value_list, |
2092 | 2557 | &uc_mgr->value_list); |
2093 | if (err >= 0) { | |
2094 | list_del(&xold->active_list); | |
2095 | list_add_tail(&xnew->active_list, &uc_mgr->active_modifiers); | |
2096 | } | |
2097 | seq_found = 1; | |
2098 | break; | |
2099 | } | |
2100 | } | |
2101 | if (!seq_found) { | |
2102 | err = set_modifier(uc_mgr, xold, 0); | |
2103 | if (err < 0) | |
2104 | return err; | |
2105 | err = set_modifier(uc_mgr, xnew, 1); | |
2106 | if (err < 0) | |
2107 | return err; | |
2108 | } | |
2109 | return err; | |
2558 | if (err >= 0) { | |
2559 | list_del(&xold->active_list); | |
2560 | list_add_tail(&xnew->active_list, &uc_mgr->active_modifiers); | |
2561 | } | |
2562 | seq_found = 1; | |
2563 | break; | |
2564 | } | |
2565 | } | |
2566 | if (!seq_found) { | |
2567 | err = set_modifier(uc_mgr, xold, 0); | |
2568 | if (err < 0) | |
2569 | return err; | |
2570 | err = set_modifier(uc_mgr, xnew, 1); | |
2571 | if (err < 0) | |
2572 | return err; | |
2573 | } | |
2574 | return err; | |
2110 | 2575 | } |
2111 | 2576 | |
2112 | 2577 | /** |
2117 | 2582 | * \return Zero if success, otherwise a negative error code |
2118 | 2583 | */ |
2119 | 2584 | int snd_use_case_set(snd_use_case_mgr_t *uc_mgr, |
2120 | const char *identifier, | |
2121 | const char *value) | |
2585 | const char *identifier, | |
2586 | const char *value) | |
2122 | 2587 | { |
2123 | 2588 | char *str, *str1; |
2124 | 2589 | int err = 0; |
2125 | 2590 | |
2126 | 2591 | pthread_mutex_lock(&uc_mgr->mutex); |
2127 | if (strcmp(identifier, "_boot") == 0) | |
2592 | if (strcmp(identifier, "_fboot") == 0) | |
2593 | err = set_fixedboot_user(uc_mgr, value); | |
2594 | else if (strcmp(identifier, "_boot") == 0) | |
2128 | 2595 | err = set_boot_user(uc_mgr, value); |
2129 | 2596 | else if (strcmp(identifier, "_defaults") == 0) |
2130 | 2597 | err = set_defaults_user(uc_mgr, value); |
2131 | 2598 | else if (strcmp(identifier, "_verb") == 0) |
2132 | err = set_verb_user(uc_mgr, value); | |
2133 | else if (strcmp(identifier, "_enadev") == 0) | |
2134 | err = set_device_user(uc_mgr, value, 1); | |
2135 | else if (strcmp(identifier, "_disdev") == 0) | |
2136 | err = set_device_user(uc_mgr, value, 0); | |
2137 | else if (strcmp(identifier, "_enamod") == 0) | |
2138 | err = set_modifier_user(uc_mgr, value, 1); | |
2139 | else if (strcmp(identifier, "_dismod") == 0) | |
2140 | err = set_modifier_user(uc_mgr, value, 0); | |
2141 | else { | |
2142 | str1 = strchr(identifier, '/'); | |
2143 | if (str1) { | |
2144 | str = strdup(str1 + 1); | |
2145 | if (str == NULL) { | |
2146 | err = -ENOMEM; | |
2147 | goto __end; | |
2148 | } | |
2149 | } else { | |
2150 | err = -EINVAL; | |
2151 | goto __end; | |
2152 | } | |
2153 | if (check_identifier(identifier, "_swdev")) | |
2154 | err = switch_device(uc_mgr, str, value); | |
2155 | else if (check_identifier(identifier, "_swmod")) | |
2156 | err = switch_modifier(uc_mgr, str, value); | |
2157 | else | |
2158 | err = -EINVAL; | |
2159 | if (str) | |
2160 | free(str); | |
2161 | } | |
2599 | err = set_verb_user(uc_mgr, value); | |
2600 | else if (strcmp(identifier, "_enadev") == 0) | |
2601 | err = set_device_user(uc_mgr, value, 1); | |
2602 | else if (strcmp(identifier, "_disdev") == 0) | |
2603 | err = set_device_user(uc_mgr, value, 0); | |
2604 | else if (strcmp(identifier, "_enamod") == 0) | |
2605 | err = set_modifier_user(uc_mgr, value, 1); | |
2606 | else if (strcmp(identifier, "_dismod") == 0) | |
2607 | err = set_modifier_user(uc_mgr, value, 0); | |
2608 | else { | |
2609 | str1 = strchr(identifier, '/'); | |
2610 | if (str1) { | |
2611 | str = strdup(str1 + 1); | |
2612 | if (str == NULL) { | |
2613 | err = -ENOMEM; | |
2614 | goto __end; | |
2615 | } | |
2616 | } else { | |
2617 | err = -EINVAL; | |
2618 | goto __end; | |
2619 | } | |
2620 | if (check_identifier(identifier, "_swdev")) | |
2621 | err = switch_device(uc_mgr, str, value); | |
2622 | else if (check_identifier(identifier, "_swmod")) | |
2623 | err = switch_modifier(uc_mgr, str, value); | |
2624 | else | |
2625 | err = -EINVAL; | |
2626 | if (str) | |
2627 | free(str); | |
2628 | } | |
2162 | 2629 | __end: |
2163 | 2630 | pthread_mutex_unlock(&uc_mgr->mutex); |
2164 | return err; | |
2631 | return err; | |
2165 | 2632 | } |
2166 | 2633 | |
2167 | 2634 | /** |
30 | 30 | */ |
31 | 31 | |
32 | 32 | #include "ucm_local.h" |
33 | #include <stdbool.h> | |
33 | 34 | #include <dirent.h> |
34 | 35 | #include <limits.h> |
35 | 36 | |
36 | /* Directories to store UCM configuration files for components, like | |
37 | * off-soc codecs or embedded DSPs. Components can define their own | |
38 | * devices and sequences, to be reused by sound cards/machines. UCM | |
39 | * manager should not scan these component directories. | |
40 | * Machine use case files can include component configratuation files | |
41 | * via alsaconf syntax: | |
42 | * <searchdir:component-directory-name> and <component-conf-file-name>. | |
43 | * Alsaconf will import the included files automatically. After including | |
44 | * a component file, a machine device's sequence can enable or disable | |
45 | * a component device via syntax: | |
46 | * enadev "component_device_name" | |
47 | * disdev "component_device_name" | |
48 | */ | |
49 | static const char * const component_dir[] = { | |
50 | "codecs", /* for off-soc codecs */ | |
51 | "dsps", /* for DSPs embedded in SoC */ | |
52 | "platforms", /* for common platform implementations */ | |
53 | NULL, /* terminator */ | |
54 | }; | |
55 | ||
56 | 37 | static int filename_filter(const struct dirent *dirent); |
57 | static int is_component_directory(const char *dir); | |
58 | 38 | |
59 | 39 | static int parse_sequence(snd_use_case_mgr_t *uc_mgr, |
60 | 40 | struct list_head *base, |
68 | 48 | { |
69 | 49 | const char *env = getenv(version > 1 ? ALSA_CONFIG_UCM2_VAR : ALSA_CONFIG_UCM_VAR); |
70 | 50 | |
51 | if (file[0] == '/') | |
52 | file++; | |
71 | 53 | if (env == NULL) |
72 | 54 | snprintf(fn, fn_len, "%s/%s/%s%s%s", |
73 | 55 | snd_config_topdir(), version > 1 ? "ucm2" : "ucm", |
91 | 73 | file); |
92 | 74 | err = uc_mgr_config_load(uc_mgr->conf_format, filename, cfg); |
93 | 75 | if (err < 0) { |
94 | uc_error("error: failed to open file %s : %d", filename, -errno); | |
76 | uc_error("error: failed to open file %s: %d", filename, err); | |
95 | 77 | return err; |
96 | 78 | } |
97 | 79 | return 0; |
420 | 402 | } |
421 | 403 | |
422 | 404 | /* |
405 | * Parse one item for alsa-lib config | |
406 | */ | |
407 | static int parse_libconfig1(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg) | |
408 | { | |
409 | snd_config_iterator_t i, next; | |
410 | snd_config_t *n, *config = NULL; | |
411 | const char *id, *file = NULL; | |
412 | bool substfile = false, substconfig = false; | |
413 | int err; | |
414 | ||
415 | if (snd_config_get_id(cfg, &id) < 0) | |
416 | return -EINVAL; | |
417 | ||
418 | if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) { | |
419 | uc_error("compound type expected for %s", id); | |
420 | return -EINVAL; | |
421 | } | |
422 | ||
423 | snd_config_for_each(i, next, cfg) { | |
424 | n = snd_config_iterator_entry(i); | |
425 | ||
426 | if (snd_config_get_id(n, &id) < 0) | |
427 | return -EINVAL; | |
428 | ||
429 | if (strcmp(id, "File") == 0 || | |
430 | strcmp(id, "SubstiFile") == 0) { | |
431 | substfile = id[0] == 'S'; | |
432 | err = snd_config_get_string(n, &file); | |
433 | if (err < 0) | |
434 | return err; | |
435 | continue; | |
436 | } | |
437 | ||
438 | if (strcmp(id, "Config") == 0 || | |
439 | strcmp(id, "SubstiConfig") == 0) { | |
440 | substconfig = id[0] == 'S'; | |
441 | if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) | |
442 | return -EINVAL; | |
443 | config = n; | |
444 | continue; | |
445 | } | |
446 | ||
447 | uc_error("unknown field %s", id); | |
448 | return -EINVAL; | |
449 | } | |
450 | ||
451 | if (file) { | |
452 | if (substfile) { | |
453 | snd_config_t *cfg; | |
454 | err = uc_mgr_config_load(uc_mgr->conf_format, file, &cfg); | |
455 | if (err < 0) | |
456 | return err; | |
457 | err = uc_mgr_substitute_tree(uc_mgr, cfg); | |
458 | if (err < 0) { | |
459 | snd_config_delete(cfg); | |
460 | return err; | |
461 | } | |
462 | err = snd_config_merge(uc_mgr->local_config, cfg, 0); | |
463 | if (err < 0) { | |
464 | snd_config_delete(cfg); | |
465 | return err; | |
466 | } | |
467 | } else { | |
468 | char filename[PATH_MAX]; | |
469 | ||
470 | ucm_filename(filename, sizeof(filename), uc_mgr->conf_format, | |
471 | file[0] == '/' ? NULL : uc_mgr->conf_dir_name, | |
472 | file); | |
473 | err = uc_mgr_config_load_into(uc_mgr->conf_format, filename, uc_mgr->local_config); | |
474 | if (err < 0) | |
475 | return err; | |
476 | } | |
477 | } | |
478 | ||
479 | if (config) { | |
480 | if (substconfig) { | |
481 | err = uc_mgr_substitute_tree(uc_mgr, config); | |
482 | if (err < 0) | |
483 | return err; | |
484 | } | |
485 | err = snd_config_merge(uc_mgr->local_config, config, 0); | |
486 | if (err < 0) | |
487 | return err; | |
488 | } | |
489 | ||
490 | return 0; | |
491 | } | |
492 | ||
493 | /* | |
494 | * Parse alsa-lib config | |
495 | */ | |
496 | static int parse_libconfig(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg) | |
497 | { | |
498 | snd_config_iterator_t i, next; | |
499 | snd_config_t *n; | |
500 | const char *id; | |
501 | int err; | |
502 | ||
503 | if (snd_config_get_id(cfg, &id) < 0) | |
504 | return -EINVAL; | |
505 | ||
506 | if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) { | |
507 | uc_error("compound type expected for %s", id); | |
508 | return -EINVAL; | |
509 | } | |
510 | ||
511 | snd_config_for_each(i, next, cfg) { | |
512 | n = snd_config_iterator_entry(i); | |
513 | ||
514 | err = parse_libconfig1(uc_mgr, n); | |
515 | if (err < 0) | |
516 | return err; | |
517 | } | |
518 | ||
519 | return 0; | |
520 | } | |
521 | ||
522 | /* | |
423 | 523 | * Parse transition |
424 | 524 | */ |
425 | 525 | static int parse_transition(snd_use_case_mgr_t *uc_mgr, |
719 | 819 | |
720 | 820 | if (strcmp(cmd, "cset") == 0) { |
721 | 821 | curr->type = SEQUENCE_ELEMENT_TYPE_CSET; |
822 | cset: | |
722 | 823 | err = parse_string_substitute3(uc_mgr, n, &curr->data.cset); |
723 | 824 | if (err < 0) { |
724 | uc_error("error: cset requires a string!"); | |
825 | uc_error("error: %s requires a string!", cmd); | |
725 | 826 | return err; |
726 | 827 | } |
727 | 828 | continue; |
753 | 854 | |
754 | 855 | if (strcmp(cmd, "cset-bin-file") == 0) { |
755 | 856 | curr->type = SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE; |
756 | err = parse_string_substitute3(uc_mgr, n, &curr->data.cset); | |
757 | if (err < 0) { | |
758 | uc_error("error: cset-bin-file requires a string!"); | |
759 | return err; | |
760 | } | |
761 | continue; | |
857 | goto cset; | |
762 | 858 | } |
763 | 859 | |
764 | 860 | if (strcmp(cmd, "cset-tlv") == 0) { |
765 | 861 | curr->type = SEQUENCE_ELEMENT_TYPE_CSET_TLV; |
766 | err = parse_string_substitute3(uc_mgr, n, &curr->data.cset); | |
767 | if (err < 0) { | |
768 | uc_error("error: cset-tlv requires a string!"); | |
862 | goto cset; | |
863 | } | |
864 | ||
865 | if (strcmp(cmd, "cset-new") == 0) { | |
866 | curr->type = SEQUENCE_ELEMENT_TYPE_CSET_NEW; | |
867 | goto cset; | |
868 | } | |
869 | ||
870 | if (strcmp(cmd, "ctl-remove") == 0) { | |
871 | curr->type = SEQUENCE_ELEMENT_TYPE_CTL_REMOVE; | |
872 | goto cset; | |
873 | } | |
874 | ||
875 | if (strcmp(cmd, "sysw") == 0) { | |
876 | curr->type = SEQUENCE_ELEMENT_TYPE_SYSSET; | |
877 | err = parse_string_substitute3(uc_mgr, n, &curr->data.sysw); | |
878 | if (err < 0) { | |
879 | uc_error("error: sysw requires a string!"); | |
769 | 880 | return err; |
770 | 881 | } |
771 | 882 | continue; |
794 | 905 | |
795 | 906 | if (strcmp(cmd, "exec") == 0) { |
796 | 907 | curr->type = SEQUENCE_ELEMENT_TYPE_EXEC; |
908 | exec: | |
797 | 909 | err = parse_string_substitute3(uc_mgr, n, &curr->data.exec); |
798 | 910 | if (err < 0) { |
799 | 911 | uc_error("error: exec requires a string!"); |
801 | 913 | } |
802 | 914 | continue; |
803 | 915 | } |
804 | ||
916 | ||
917 | if (strcmp(cmd, "shell") == 0) { | |
918 | curr->type = SEQUENCE_ELEMENT_TYPE_SHELL; | |
919 | goto exec; | |
920 | } | |
921 | ||
922 | if (strcmp(cmd, "cfg-save") == 0) { | |
923 | curr->type = SEQUENCE_ELEMENT_TYPE_CFGSAVE; | |
924 | err = parse_string_substitute3(uc_mgr, n, &curr->data.cfgsave); | |
925 | if (err < 0) { | |
926 | uc_error("error: sysw requires a string!"); | |
927 | return err; | |
928 | } | |
929 | continue; | |
930 | } | |
931 | ||
932 | if (strcmp(cmd, "comment") == 0) | |
933 | goto skip; | |
934 | ||
935 | uc_error("error: sequence command '%s' is ignored", cmd); | |
936 | ||
937 | skip: | |
805 | 938 | list_del(&curr->list); |
806 | 939 | uc_mgr_free_sequence_element(curr); |
807 | 940 | } |
1574 | 1707 | /* in-place evaluation */ |
1575 | 1708 | err = uc_mgr_evaluate_inplace(uc_mgr, cfg); |
1576 | 1709 | if (err < 0) |
1577 | return err; | |
1710 | goto _err; | |
1578 | 1711 | |
1579 | 1712 | /* parse master config sections */ |
1580 | 1713 | snd_config_for_each(i, next, cfg) { |
1626 | 1759 | file); |
1627 | 1760 | goto _err; |
1628 | 1761 | } |
1762 | continue; | |
1629 | 1763 | } |
1630 | 1764 | |
1631 | 1765 | /* device remove */ |
1636 | 1770 | file); |
1637 | 1771 | goto _err; |
1638 | 1772 | } |
1773 | continue; | |
1774 | } | |
1775 | ||
1776 | /* alsa-lib configuration */ | |
1777 | if (uc_mgr->conf_format > 3 && strcmp(id, "LibraryConfig") == 0) { | |
1778 | err = parse_libconfig(uc_mgr, n); | |
1779 | if (err < 0) { | |
1780 | uc_error("error: failed to parse LibConfig"); | |
1781 | goto _err; | |
1782 | } | |
1783 | continue; | |
1639 | 1784 | } |
1640 | 1785 | } |
1641 | 1786 | |
1736 | 1881 | free(file); |
1737 | 1882 | free(comment); |
1738 | 1883 | return err; |
1884 | } | |
1885 | ||
1886 | /* | |
1887 | * parse controls which should be run only at initial boot (forcefully) | |
1888 | */ | |
1889 | static int parse_controls_fixedboot(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg) | |
1890 | { | |
1891 | int err; | |
1892 | ||
1893 | if (!list_empty(&uc_mgr->fixedboot_list)) { | |
1894 | uc_error("FixedBoot list is not empty"); | |
1895 | return -EINVAL; | |
1896 | } | |
1897 | err = parse_sequence(uc_mgr, &uc_mgr->fixedboot_list, cfg); | |
1898 | if (err < 0) { | |
1899 | uc_error("Unable to parse FixedBootSequence"); | |
1900 | return err; | |
1901 | } | |
1902 | ||
1903 | return 0; | |
1739 | 1904 | } |
1740 | 1905 | |
1741 | 1906 | /* |
1890 | 2055 | continue; |
1891 | 2056 | } |
1892 | 2057 | |
2058 | /* find default control values section (force boot sequence only) */ | |
2059 | if (strcmp(id, "FixedBootSequence") == 0) { | |
2060 | err = parse_controls_fixedboot(uc_mgr, n); | |
2061 | if (err < 0) | |
2062 | return err; | |
2063 | continue; | |
2064 | } | |
2065 | ||
1893 | 2066 | /* find default control values section (first boot only) */ |
1894 | 2067 | if (strcmp(id, "BootSequence") == 0) { |
1895 | 2068 | err = parse_controls_boot(uc_mgr, n); |
1916 | 2089 | continue; |
1917 | 2090 | } |
1918 | 2091 | |
2092 | /* alsa-lib configuration */ | |
2093 | if (uc_mgr->conf_format > 3 && strcmp(id, "LibraryConfig") == 0) { | |
2094 | err = parse_libconfig(uc_mgr, n); | |
2095 | if (err < 0) { | |
2096 | uc_error("error: failed to parse LibraryConfig"); | |
2097 | return err; | |
2098 | } | |
2099 | continue; | |
2100 | } | |
2101 | ||
1919 | 2102 | /* error */ |
1920 | 2103 | if (strcmp(id, "Error") == 0) |
1921 | 2104 | return error_node(uc_mgr, n); |
1922 | 2105 | |
1923 | uc_error("uknown master file field %s", id); | |
2106 | uc_error("unknown master file field %s", id); | |
1924 | 2107 | } |
1925 | 2108 | return 0; |
1926 | 2109 | } |
2159 | 2342 | continue; |
2160 | 2343 | } |
2161 | 2344 | |
2162 | uc_error("uknown toplevel field %s", id); | |
2345 | /* alsa-lib configuration */ | |
2346 | if (uc_mgr->conf_format > 3 && strcmp(id, "LibraryConfig") == 0) { | |
2347 | err = parse_libconfig(uc_mgr, n); | |
2348 | if (err < 0) { | |
2349 | uc_error("error: failed to parse LibConfig"); | |
2350 | return err; | |
2351 | } | |
2352 | continue; | |
2353 | } | |
2354 | ||
2355 | uc_error("unknown toplevel field %s", id); | |
2163 | 2356 | } |
2164 | 2357 | |
2165 | 2358 | return -ENOENT; |
2259 | 2452 | return 0; |
2260 | 2453 | } |
2261 | 2454 | |
2262 | /* whether input dir is a predefined component directory */ | |
2263 | static int is_component_directory(const char *dir) | |
2264 | { | |
2265 | int i = 0; | |
2266 | ||
2267 | while (component_dir[i]) { | |
2268 | if (!strncmp(dir, component_dir[i], PATH_MAX)) | |
2269 | return 1; | |
2270 | i++; | |
2271 | }; | |
2272 | ||
2273 | return 0; | |
2274 | } | |
2275 | ||
2276 | 2455 | /* scan all cards and comments |
2277 | 2456 | * |
2278 | 2457 | * Cards are defined by machines. Each card/machine installs its UCM |
2293 | 2472 | struct dirent **namelist; |
2294 | 2473 | |
2295 | 2474 | if (env) |
2296 | snprintf(filename, sizeof(filename), "%s", env); | |
2475 | snprintf(filename, sizeof(filename), "%s/conf.virt.d", env); | |
2297 | 2476 | else |
2298 | snprintf(filename, sizeof(filename), "%s/ucm2", | |
2477 | snprintf(filename, sizeof(filename), "%s/ucm2/conf.virt.d", | |
2299 | 2478 | snd_config_topdir()); |
2300 | 2479 | |
2301 | 2480 | #if defined(_GNU_SOURCE) && !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__sun) && !defined(ANDROID) |
2336 | 2515 | |
2337 | 2516 | d_name = namelist[i]->d_name; |
2338 | 2517 | |
2339 | /* Skip the directories for component devices */ | |
2340 | if (is_component_directory(d_name)) | |
2341 | continue; | |
2342 | ||
2343 | 2518 | snprintf(fn, sizeof(fn), "%s.conf", d_name); |
2344 | 2519 | ucm_filename(filename, sizeof(filename), 2, d_name, fn); |
2520 | #ifdef HAVE_EACCESS | |
2345 | 2521 | if (eaccess(filename, R_OK)) |
2522 | #else | |
2523 | if (access(filename, R_OK)) | |
2524 | #endif | |
2346 | 2525 | continue; |
2347 | 2526 | |
2348 | 2527 | err = uc_mgr_config_load(2, filename, &cfg); |
159 | 159 | if (err < 0) |
160 | 160 | return err; |
161 | 161 | err = regcomp(&re, s, options); |
162 | if (err) { | |
163 | uc_error("Regex '%s' compilation failed (code %d)", s, err); | |
164 | free(s); | |
165 | return -EINVAL; | |
166 | } | |
162 | 167 | free(s); |
163 | if (err) { | |
164 | uc_error("Regex '%s' compilation failed (code %d)", err); | |
165 | return -EINVAL; | |
166 | } | |
167 | 168 | |
168 | 169 | err = uc_mgr_get_substituted_value(uc_mgr, &s, string); |
169 | 170 | if (err < 0) { |
268 | 269 | return 1; |
269 | 270 | } |
270 | 271 | |
272 | static int if_eval_path(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval) | |
273 | { | |
274 | const char *path, *mode = ""; | |
275 | int err, amode = F_OK; | |
276 | ||
277 | if (uc_mgr->conf_format < 4) { | |
278 | uc_error("Path condition is supported in v4+ syntax"); | |
279 | return -EINVAL; | |
280 | } | |
281 | ||
282 | err = get_string(eval, "Path", &path); | |
283 | if (err < 0) { | |
284 | uc_error("Path error (If.Condition.Path)"); | |
285 | return -EINVAL; | |
286 | } | |
287 | ||
288 | err = get_string(eval, "Mode", &mode); | |
289 | if (err < 0 && err != -ENOENT) { | |
290 | uc_error("Path error (If.Condition.Mode)"); | |
291 | return -EINVAL; | |
292 | } | |
293 | ||
294 | if (strncasecmp(mode, "exist", 5) == 0) { | |
295 | amode = F_OK; | |
296 | } else if (strcasecmp(mode, "read") == 0) { | |
297 | amode = R_OK; | |
298 | } else if (strcasecmp(mode, "write") == 0) { | |
299 | amode = W_OK; | |
300 | } else if (strcasecmp(mode, "exec") == 0) { | |
301 | amode = X_OK; | |
302 | } else { | |
303 | uc_error("Path unknown mode (If.Condition.Mode)"); | |
304 | return -EINVAL; | |
305 | } | |
306 | ||
307 | #ifdef HAVE_EACCESS | |
308 | if (eaccess(path, amode)) | |
309 | #else | |
310 | if (access(path, amode)) | |
311 | #endif | |
312 | return 0; | |
313 | ||
314 | return 1; | |
315 | } | |
316 | ||
271 | 317 | static int if_eval(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval) |
272 | 318 | { |
273 | 319 | const char *type; |
295 | 341 | |
296 | 342 | if (strcmp(type, "RegexMatch") == 0) |
297 | 343 | return if_eval_regex_match(uc_mgr, eval); |
344 | ||
345 | if (strcmp(type, "Path") == 0) | |
346 | return if_eval_path(uc_mgr, eval); | |
298 | 347 | |
299 | 348 | uc_error("unknown If.Condition.Type"); |
300 | 349 | return -EINVAL; |
0 | /* | |
1 | * Exec an external program | |
2 | * Copyright (C) 2021 Jaroslav Kysela | |
3 | * | |
4 | * This library is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU Lesser General Public | |
6 | * License as published by the Free Software Foundation; either | |
7 | * version 2 of the License, or (at your option) any later version. | |
8 | * | |
9 | * This library is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | * Lesser General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU Lesser General Public | |
15 | * License along with this library; if not, write to the Free Software | |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
17 | * | |
18 | * Support for the verb/device/modifier core logic and API, | |
19 | * command line tool and file parser was kindly sponsored by | |
20 | * Texas Instruments Inc. | |
21 | * Support for multiple active modifiers and devices, | |
22 | * transition sequences, multiple client access and user defined use | |
23 | * cases was kindly sponsored by Wolfson Microelectronics PLC. | |
24 | * | |
25 | * Copyright (C) 2021 Red Hat Inc. | |
26 | * Authors: Jaroslav Kysela <perex@perex.cz> | |
27 | */ | |
28 | ||
29 | #include "ucm_local.h" | |
30 | #include <sys/stat.h> | |
31 | #include <sys/wait.h> | |
32 | #include <limits.h> | |
33 | #include <dirent.h> | |
34 | ||
35 | static pthread_mutex_t fork_lock = PTHREAD_MUTEX_INITIALIZER; | |
36 | ||
37 | /* | |
38 | * Search PATH for executable | |
39 | */ | |
40 | static int find_exec(const char *name, char *out, size_t len) | |
41 | { | |
42 | int ret = 0; | |
43 | char bin[PATH_MAX]; | |
44 | char *path, *tmp, *tmp2 = NULL; | |
45 | DIR *dir; | |
46 | struct dirent *de; | |
47 | struct stat st; | |
48 | if (name[0] == '/') { | |
49 | if (lstat(name, &st)) | |
50 | return 0; | |
51 | if (!S_ISREG(st.st_mode) || !(st.st_mode & S_IEXEC)) | |
52 | return 0; | |
53 | snd_strlcpy(out, name, len); | |
54 | return 1; | |
55 | } | |
56 | if (!(tmp = getenv("PATH"))) | |
57 | return 0; | |
58 | path = alloca(strlen(tmp) + 1); | |
59 | if (!path) | |
60 | return 0; | |
61 | strcpy(path, tmp); | |
62 | tmp = strtok_r(path, ":", &tmp2); | |
63 | while (tmp && !ret) { | |
64 | if ((dir = opendir(tmp))) { | |
65 | while ((de = readdir(dir))) { | |
66 | if (strstr(de->d_name, name) != de->d_name) | |
67 | continue; | |
68 | snprintf(bin, sizeof(bin), "%s/%s", tmp, | |
69 | de->d_name); | |
70 | if (lstat(bin, &st)) | |
71 | continue; | |
72 | if (!S_ISREG(st.st_mode) | |
73 | || !(st.st_mode & S_IEXEC)) | |
74 | continue; | |
75 | snd_strlcpy(out, bin, len); | |
76 | closedir(dir); | |
77 | return 1; | |
78 | } | |
79 | closedir(dir); | |
80 | } | |
81 | tmp = strtok_r(NULL, ":", &tmp2); | |
82 | } | |
83 | return ret; | |
84 | } | |
85 | ||
86 | static void free_args(char **argv) | |
87 | { | |
88 | char **a; | |
89 | ||
90 | for (a = argv; *a; a++) | |
91 | free(*a); | |
92 | free(argv); | |
93 | } | |
94 | ||
95 | static int parse_args(char ***argv, int argc, const char *cmd) | |
96 | { | |
97 | char *s, *f; | |
98 | int i = 0, l, eow; | |
99 | ||
100 | if (!argv || !cmd) | |
101 | return -1; | |
102 | ||
103 | s = alloca(strlen(cmd) + 1); | |
104 | if (!s) | |
105 | return -1; | |
106 | strcpy(s, cmd); | |
107 | *argv = calloc(argc, sizeof(char *)); | |
108 | ||
109 | while (*s && i < argc - 1) { | |
110 | while (*s == ' ') | |
111 | s++; | |
112 | f = s; | |
113 | eow = 0; | |
114 | while (*s) { | |
115 | if (*s == '\\') { | |
116 | l = *(s + 1); | |
117 | if (l == 'b') | |
118 | l = '\b'; | |
119 | else if (l == 'f') | |
120 | l = '\f'; | |
121 | else if (l == 'n') | |
122 | l = '\n'; | |
123 | else if (l == 'r') | |
124 | l = '\r'; | |
125 | else if (l == 't') | |
126 | l = '\t'; | |
127 | else | |
128 | l = 0; | |
129 | if (l) { | |
130 | *s++ = l; | |
131 | memmove(s, s + 1, strlen(s)); | |
132 | } else { | |
133 | memmove(s, s + 1, strlen(s)); | |
134 | if (*s) | |
135 | s++; | |
136 | } | |
137 | } else if (eow) { | |
138 | if (*s == eow) { | |
139 | memmove(s, s + 1, strlen(s)); | |
140 | eow = 0; | |
141 | } else { | |
142 | s++; | |
143 | } | |
144 | } else if (*s == '\'' || *s == '"') { | |
145 | eow = *s; | |
146 | memmove(s, s + 1, strlen(s)); | |
147 | } else if (*s == ' ') { | |
148 | break; | |
149 | } else { | |
150 | s++; | |
151 | } | |
152 | } | |
153 | if (f != s) { | |
154 | if (*s) { | |
155 | *(char *)s = '\0'; | |
156 | s++; | |
157 | } | |
158 | (*argv)[i] = strdup(f); | |
159 | if ((*argv)[i] == NULL) { | |
160 | free_args(*argv); | |
161 | return -ENOMEM; | |
162 | } | |
163 | i++; | |
164 | } | |
165 | } | |
166 | (*argv)[i] = NULL; | |
167 | return 0; | |
168 | } | |
169 | ||
170 | /* | |
171 | * execute a binary file | |
172 | * | |
173 | */ | |
174 | int uc_mgr_exec(const char *prog) | |
175 | { | |
176 | pid_t p, f, maxfd; | |
177 | int err = 0, status; | |
178 | char bin[PATH_MAX]; | |
179 | struct sigaction sa; | |
180 | struct sigaction intr, quit; | |
181 | sigset_t omask; | |
182 | char **argv; | |
183 | ||
184 | if (parse_args(&argv, 32, prog)) | |
185 | return -EINVAL; | |
186 | ||
187 | prog = argv[0]; | |
188 | if (prog == NULL) { | |
189 | err = -EINVAL; | |
190 | goto __error; | |
191 | } | |
192 | if (prog[0] != '/' && prog[0] != '.') { | |
193 | if (!find_exec(argv[0], bin, sizeof(bin))) { | |
194 | err = -ENOEXEC; | |
195 | goto __error; | |
196 | } | |
197 | prog = bin; | |
198 | } | |
199 | ||
200 | maxfd = sysconf(_SC_OPEN_MAX); | |
201 | ||
202 | /* | |
203 | * block SIGCHLD signal | |
204 | * ignore SIGINT and SIGQUIT in parent | |
205 | */ | |
206 | ||
207 | memset(&sa, 0, sizeof(sa)); | |
208 | sa.sa_handler = SIG_IGN; | |
209 | sigemptyset(&sa.sa_mask); | |
210 | sigaddset(&sa.sa_mask, SIGCHLD); | |
211 | ||
212 | pthread_mutex_lock(&fork_lock); | |
213 | ||
214 | sigprocmask(SIG_BLOCK, &sa.sa_mask, &omask); | |
215 | ||
216 | sigaction(SIGINT, &sa, &intr); | |
217 | sigaction(SIGQUIT, &sa, &quit); | |
218 | ||
219 | p = fork(); | |
220 | ||
221 | if (p == -1) { | |
222 | err = -errno; | |
223 | pthread_mutex_unlock(&fork_lock); | |
224 | uc_error("Unable to fork() for \"%s\" -- %s", prog, | |
225 | strerror(errno)); | |
226 | goto __error; | |
227 | } | |
228 | ||
229 | if (p == 0) { | |
230 | f = open("/dev/null", O_RDWR); | |
231 | if (f == -1) { | |
232 | uc_error("pid %d cannot open /dev/null for redirect %s -- %s", | |
233 | getpid(), prog, strerror(errno)); | |
234 | exit(1); | |
235 | } | |
236 | ||
237 | close(0); | |
238 | close(1); | |
239 | close(2); | |
240 | ||
241 | dup2(f, 0); | |
242 | dup2(f, 1); | |
243 | dup2(f, 2); | |
244 | ||
245 | close(f); | |
246 | ||
247 | for (f = 3; f < maxfd; f++) | |
248 | close(f); | |
249 | ||
250 | /* install default handlers for the forked process */ | |
251 | signal(SIGINT, SIG_DFL); | |
252 | signal(SIGQUIT, SIG_DFL); | |
253 | ||
254 | execve(prog, argv, environ); | |
255 | exit(1); | |
256 | } | |
257 | ||
258 | sigaction(SIGINT, &intr, NULL); | |
259 | sigaction(SIGQUIT, &quit, NULL); | |
260 | sigprocmask(SIG_SETMASK, &omask, NULL); | |
261 | ||
262 | pthread_mutex_unlock(&fork_lock); | |
263 | ||
264 | /* make the spawned process a session leader so killing the | |
265 | process group recursively kills any child process that | |
266 | might have been spawned */ | |
267 | setpgid(p, p); | |
268 | ||
269 | while (1) { | |
270 | f = waitpid(p, &status, 0); | |
271 | if (f == -1) { | |
272 | if (errno == EAGAIN) | |
273 | continue; | |
274 | err = -errno; | |
275 | goto __error; | |
276 | } | |
277 | if (WIFSIGNALED(status)) { | |
278 | err = -EINTR; | |
279 | break; | |
280 | } | |
281 | if (WIFEXITED(status)) { | |
282 | err = WEXITSTATUS(status); | |
283 | break; | |
284 | } | |
285 | } | |
286 | ||
287 | __error: | |
288 | free_args(argv); | |
289 | return err; | |
290 | } |
107 | 107 | return 0; |
108 | 108 | } |
109 | 109 | |
110 | static int merge_it(snd_config_t *dst, snd_config_t *n, snd_config_t **_dn) | |
111 | { | |
112 | snd_config_t *dn; | |
113 | const char *id; | |
114 | int err; | |
115 | ||
116 | err = snd_config_get_id(n, &id); | |
117 | if (err < 0) | |
118 | return err; | |
119 | err = snd_config_search(dst, id, &dn); | |
120 | if (err < 0) | |
121 | return err; | |
122 | err = snd_config_merge(dn, n, 0); /* merge / append mode */ | |
123 | if (err < 0) | |
124 | snd_config_delete(n); | |
125 | else | |
126 | *_dn = dn; | |
127 | return err; | |
128 | } | |
129 | ||
110 | 130 | static int compound_merge(const char *id, |
111 | 131 | snd_config_t *dst, snd_config_t *src, |
112 | 132 | snd_config_t *before, snd_config_t *after) |
131 | 151 | if (err < 0) |
132 | 152 | return err; |
133 | 153 | } |
154 | ||
155 | /* direct merge? */ | |
156 | if (!_before && !_after) | |
157 | return snd_config_merge(dst, src, 0); /* merge / append mode */ | |
134 | 158 | |
135 | 159 | if (_before && _after) { |
136 | 160 | uc_error("defined both before and after identifiers in the If or Include block"); |
174 | 198 | } |
175 | 199 | if (_before) { |
176 | 200 | err = snd_config_add_before(_before, n); |
201 | if (err == -EEXIST) | |
202 | err = merge_it(dst, n, &n); | |
177 | 203 | if (err < 0) |
178 | 204 | return err; |
179 | 205 | _before = NULL; |
180 | 206 | _after = n; |
181 | 207 | } else if (_after) { |
182 | 208 | err = snd_config_add_after(_after, n); |
209 | if (err == -EEXIST) | |
210 | err = merge_it(dst, n, &n); | |
183 | 211 | if (err < 0) |
184 | 212 | return err; |
185 | 213 | _after = n; |
186 | } else { | |
187 | err = snd_config_add(dst, n); | |
188 | if (err < 0) | |
189 | return err; | |
190 | 214 | } |
191 | 215 | } |
192 | 216 | |
202 | 226 | } |
203 | 227 | } |
204 | 228 | |
229 | snd_config_delete(src); | |
205 | 230 | return 0; |
206 | 231 | } |
207 | 232 | |
229 | 254 | err = snd_config_add(parent, n); |
230 | 255 | if (err < 0) |
231 | 256 | return err; |
232 | continue; | |
233 | 257 | } else { |
234 | 258 | err = snd_config_search(parent, id, &parent2); |
235 | 259 | if (err == -ENOENT) |
236 | 260 | goto __add; |
237 | 261 | err = compound_merge(id, parent2, n, before, after); |
238 | if (err < 0) | |
239 | return err; | |
240 | } | |
241 | snd_config_delete(n); | |
262 | if (err < 0) { | |
263 | snd_config_delete(n); | |
264 | return err; | |
265 | } | |
266 | } | |
242 | 267 | } |
243 | 268 | return 0; |
244 | 269 | } |
39 | 39 | #include <pthread.h> |
40 | 40 | #include "use-case.h" |
41 | 41 | |
42 | #define SYNTAX_VERSION_MAX 3 | |
42 | #define SYNTAX_VERSION_MAX 4 | |
43 | 43 | |
44 | 44 | #define MAX_CARD_SHORT_NAME 32 |
45 | 45 | #define MAX_CARD_LONG_NAME 80 |
46 | 46 | |
47 | #define SEQUENCE_ELEMENT_TYPE_CDEV 1 | |
48 | #define SEQUENCE_ELEMENT_TYPE_CSET 2 | |
49 | #define SEQUENCE_ELEMENT_TYPE_SLEEP 3 | |
50 | #define SEQUENCE_ELEMENT_TYPE_EXEC 4 | |
51 | #define SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE 5 | |
52 | #define SEQUENCE_ELEMENT_TYPE_CSET_TLV 6 | |
53 | #define SEQUENCE_ELEMENT_TYPE_CMPT_SEQ 7 | |
47 | #define SEQUENCE_ELEMENT_TYPE_CDEV 1 | |
48 | #define SEQUENCE_ELEMENT_TYPE_CSET 2 | |
49 | #define SEQUENCE_ELEMENT_TYPE_SLEEP 3 | |
50 | #define SEQUENCE_ELEMENT_TYPE_EXEC 4 | |
51 | #define SEQUENCE_ELEMENT_TYPE_SHELL 5 | |
52 | #define SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE 6 | |
53 | #define SEQUENCE_ELEMENT_TYPE_CSET_TLV 7 | |
54 | #define SEQUENCE_ELEMENT_TYPE_CSET_NEW 8 | |
55 | #define SEQUENCE_ELEMENT_TYPE_CTL_REMOVE 9 | |
56 | #define SEQUENCE_ELEMENT_TYPE_CMPT_SEQ 10 | |
57 | #define SEQUENCE_ELEMENT_TYPE_SYSSET 11 | |
58 | #define SEQUENCE_ELEMENT_TYPE_CFGSAVE 12 | |
54 | 59 | |
55 | 60 | struct ucm_value { |
56 | 61 | struct list_head list; |
72 | 77 | char *cdev; |
73 | 78 | char *cset; |
74 | 79 | char *exec; |
80 | char *sysw; | |
81 | char *cfgsave; | |
75 | 82 | struct component_sequence cmpt_seq; /* component sequence */ |
76 | 83 | } data; |
77 | 84 | }; |
115 | 122 | snd_ctl_t *ctl; |
116 | 123 | snd_ctl_card_info_t *ctl_info; |
117 | 124 | int slave; |
125 | int ucm_group; | |
118 | 126 | }; |
119 | 127 | |
120 | 128 | struct ucm_dev_name { |
217 | 225 | char *conf_dir_name; |
218 | 226 | char *comment; |
219 | 227 | int conf_format; |
228 | unsigned int ucm_card_number; | |
229 | ||
230 | /* UCM cards list */ | |
231 | struct list_head cards_list; | |
220 | 232 | |
221 | 233 | /* use case verb, devices and modifier configs parsed from files */ |
222 | 234 | struct list_head verb_list; |
235 | ||
236 | /* force boot settings - sequence */ | |
237 | struct list_head fixedboot_list; | |
223 | 238 | |
224 | 239 | /* boot settings - sequence */ |
225 | 240 | struct list_head boot_list; |
244 | 259 | |
245 | 260 | /* list of opened control devices */ |
246 | 261 | struct list_head ctl_list; |
262 | ||
263 | /* local library configuration */ | |
264 | snd_config_t *local_config; | |
247 | 265 | |
248 | 266 | /* Components don't define cdev, the card device. When executing |
249 | 267 | * a sequence of a component device, ucm manager enters component |
265 | 283 | void uc_mgr_error(const char *fmt, ...); |
266 | 284 | void uc_mgr_stdout(const char *fmt, ...); |
267 | 285 | |
286 | const char *uc_mgr_sysfs_root(void); | |
268 | 287 | const char *uc_mgr_config_dir(int format); |
288 | int uc_mgr_config_load_into(int format, const char *file, snd_config_t *cfg); | |
269 | 289 | int uc_mgr_config_load(int format, const char *file, snd_config_t **cfg); |
270 | 290 | int uc_mgr_config_load_file(snd_use_case_mgr_t *uc_mgr, const char *file, snd_config_t **cfg); |
271 | 291 | int uc_mgr_import_master_config(snd_use_case_mgr_t *uc_mgr); |
282 | 302 | void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr); |
283 | 303 | void uc_mgr_free(snd_use_case_mgr_t *uc_mgr); |
284 | 304 | |
305 | static inline int uc_mgr_has_local_config(snd_use_case_mgr_t *uc_mgr) | |
306 | { | |
307 | return uc_mgr && snd_config_iterator_first(uc_mgr->local_config) != | |
308 | snd_config_iterator_end(uc_mgr->local_config); | |
309 | } | |
310 | ||
311 | int uc_mgr_card_open(snd_use_case_mgr_t *uc_mgr); | |
312 | void uc_mgr_card_close(snd_use_case_mgr_t *uc_mgr); | |
313 | ||
285 | 314 | int uc_mgr_open_ctl(snd_use_case_mgr_t *uc_mgr, |
286 | 315 | struct ctl_list **ctl_list, |
287 | 316 | const char *device, |
288 | 317 | int slave); |
289 | 318 | |
290 | 319 | struct ctl_list *uc_mgr_get_master_ctl(snd_use_case_mgr_t *uc_mgr); |
320 | struct ctl_list *uc_mgr_get_ctl_by_card(snd_use_case_mgr_t *uc_mgr, int card); | |
291 | 321 | struct ctl_list *uc_mgr_get_ctl_by_name(snd_use_case_mgr_t *uc_mgr, |
292 | 322 | const char *name, int idx); |
293 | 323 | snd_ctl_t *uc_mgr_get_ctl(snd_use_case_mgr_t *uc_mgr); |
328 | 358 | const char *name, |
329 | 359 | snd_config_t *eval); |
330 | 360 | |
361 | int uc_mgr_exec(const char *prog); | |
362 | ||
331 | 363 | /** The name of the environment variable containing the UCM directory */ |
332 | 364 | #define ALSA_CONFIG_UCM_VAR "ALSA_CONFIG_UCM" |
333 | 365 |
165 | 165 | err = regexec(&re, s, ARRAY_SIZE(match), match, 0); |
166 | 166 | if (err < 0) |
167 | 167 | err = -errno; |
168 | else if (err == REG_NOMATCH) | |
169 | err = 0; | |
168 | 170 | else |
169 | 171 | err = set_variables(uc_mgr, s, ARRAY_SIZE(match), match, name); |
170 | 172 | free(s); |
27 | 27 | #include <stdbool.h> |
28 | 28 | #include <sys/stat.h> |
29 | 29 | #include <limits.h> |
30 | #include <regex.h> | |
30 | 31 | |
31 | 32 | static char *rval_open_name(snd_use_case_mgr_t *uc_mgr) |
32 | 33 | { |
40 | 41 | return strdup(name); |
41 | 42 | } |
42 | 43 | return NULL; |
44 | } | |
45 | ||
46 | static char *rval_conf_libdir(snd_use_case_mgr_t *uc_mgr) | |
47 | { | |
48 | if (uc_mgr->conf_format < 4) | |
49 | return NULL; | |
50 | return strdup(snd_config_topdir()); | |
43 | 51 | } |
44 | 52 | |
45 | 53 | static char *rval_conf_topdir(snd_use_case_mgr_t *uc_mgr) |
160 | 168 | return NULL; |
161 | 169 | } |
162 | 170 | |
171 | uc_error("${CardNumberByName} substitution is obsolete - use ${find-card}!"); | |
172 | ||
163 | 173 | return get_card_number(get_ctl_list_by_name(uc_mgr, id)); |
164 | 174 | } |
165 | 175 | |
172 | 182 | return NULL; |
173 | 183 | } |
174 | 184 | |
185 | uc_error("${CardIdByName} substitution is obsolete - use ${find-card}!"); | |
186 | ||
175 | 187 | ctl_list = get_ctl_list_by_name(uc_mgr, id); |
176 | 188 | if (ctl_list == NULL) |
177 | 189 | return NULL; |
178 | 190 | return strdup(snd_ctl_card_info_get_id(ctl_list->ctl_info)); |
191 | } | |
192 | ||
193 | typedef struct lookup_iterate *(*lookup_iter_fcn_t) | |
194 | (snd_use_case_mgr_t *uc_mgr, struct lookup_iterate *iter); | |
195 | typedef const char *(*lookup_fcn_t)(void *); | |
196 | ||
197 | struct lookup_fcn { | |
198 | char *name; | |
199 | const char *(*fcn)(void *opaque); | |
200 | }; | |
201 | ||
202 | struct lookup_iterate { | |
203 | int (*init)(snd_use_case_mgr_t *uc_mgr, struct lookup_iterate *iter, | |
204 | snd_config_t *config); | |
205 | void (*done)(struct lookup_iterate *iter); | |
206 | lookup_iter_fcn_t first; | |
207 | lookup_iter_fcn_t next; | |
208 | char *(*retfcn)(struct lookup_iterate *iter, snd_config_t *config); | |
209 | struct lookup_fcn *fcns; | |
210 | lookup_fcn_t fcn; | |
211 | struct ctl_list *ctl_list; | |
212 | void *info; | |
213 | }; | |
214 | ||
215 | static snd_config_t *parse_lookup_query(const char *query) | |
216 | { | |
217 | snd_input_t *input; | |
218 | snd_config_t *config; | |
219 | int err; | |
220 | ||
221 | err = snd_input_buffer_open(&input, query, strlen(query)); | |
222 | if (err < 0) { | |
223 | uc_error("unable to create memory input buffer"); | |
224 | return NULL; | |
225 | } | |
226 | err = snd_config_top(&config); | |
227 | if (err < 0) { | |
228 | snd_input_close(input); | |
229 | return NULL; | |
230 | } | |
231 | err = snd_config_load(config, input); | |
232 | snd_input_close(input); | |
233 | if (err < 0) { | |
234 | snd_config_delete(config); | |
235 | uc_error("wrong arguments '%s'", query); | |
236 | return NULL; | |
237 | } | |
238 | return config; | |
239 | } | |
240 | ||
241 | static char *rval_lookup_main(snd_use_case_mgr_t *uc_mgr, | |
242 | const char *query, | |
243 | struct lookup_iterate *iter) | |
244 | { | |
245 | snd_config_t *config, *d; | |
246 | struct lookup_fcn *fcn; | |
247 | struct lookup_iterate *curr; | |
248 | const char *s; | |
249 | char *result; | |
250 | regmatch_t match[1]; | |
251 | regex_t re; | |
252 | int err; | |
253 | ||
254 | if (uc_mgr->conf_format < 4) { | |
255 | uc_error("Lookups are supported in v4+ syntax"); | |
256 | return NULL; | |
257 | } | |
258 | ||
259 | config = parse_lookup_query(query); | |
260 | if (config == NULL) | |
261 | return NULL; | |
262 | if (iter->init && iter->init(uc_mgr, iter, config)) | |
263 | goto null; | |
264 | if (snd_config_search(config, "field", &d)) { | |
265 | uc_error("Lookups require field!"); | |
266 | goto null; | |
267 | } | |
268 | if (snd_config_get_string(d, &s)) | |
269 | goto null; | |
270 | for (fcn = iter->fcns ; fcn; fcn++) { | |
271 | if (strcasecmp(fcn->name, s) == 0) { | |
272 | iter->fcn = fcn->fcn; | |
273 | break; | |
274 | } | |
275 | } | |
276 | if (iter->fcn == NULL) { | |
277 | uc_error("Unknown field value '%s'", s); | |
278 | goto null; | |
279 | } | |
280 | if (snd_config_search(config, "regex", &d)) { | |
281 | uc_error("Lookups require regex!"); | |
282 | goto null; | |
283 | } | |
284 | if (snd_config_get_string(d, &s)) | |
285 | goto null; | |
286 | err = regcomp(&re, s, REG_EXTENDED | REG_ICASE); | |
287 | if (err) { | |
288 | uc_error("Regex '%s' compilation failed (code %d)", s, err); | |
289 | goto null; | |
290 | } | |
291 | ||
292 | result = NULL; | |
293 | for (curr = iter->first(uc_mgr, iter); curr; curr = iter->next(uc_mgr, iter)) { | |
294 | s = curr->fcn(iter->info); | |
295 | if (s == NULL) | |
296 | continue; | |
297 | if (regexec(&re, s, ARRAY_SIZE(match), match, 0) == 0) { | |
298 | result = curr->retfcn(iter, config); | |
299 | break; | |
300 | } | |
301 | } | |
302 | regfree(&re); | |
303 | fin: | |
304 | snd_config_delete(config); | |
305 | if (iter->done) | |
306 | iter->done(iter); | |
307 | return result; | |
308 | null: | |
309 | result = NULL; | |
310 | goto fin; | |
311 | } | |
312 | ||
313 | static struct lookup_iterate *rval_card_lookup1(snd_use_case_mgr_t *uc_mgr, | |
314 | struct lookup_iterate *iter, | |
315 | int card) | |
316 | { | |
317 | if (snd_card_next(&card) < 0 || card < 0) | |
318 | return NULL; | |
319 | iter->ctl_list = uc_mgr_get_ctl_by_card(uc_mgr, card); | |
320 | if (iter->ctl_list == NULL) | |
321 | return NULL; | |
322 | iter->info = iter->ctl_list->ctl_info; | |
323 | return iter; | |
324 | } | |
325 | ||
326 | static struct lookup_iterate *rval_card_lookup_first(snd_use_case_mgr_t *uc_mgr, | |
327 | struct lookup_iterate *iter) | |
328 | { | |
329 | return rval_card_lookup1(uc_mgr, iter, -1); | |
330 | } | |
331 | ||
332 | static struct lookup_iterate *rval_card_lookup_next(snd_use_case_mgr_t *uc_mgr, | |
333 | struct lookup_iterate *iter) | |
334 | { | |
335 | return rval_card_lookup1(uc_mgr, iter, snd_ctl_card_info_get_card(iter->info)); | |
336 | } | |
337 | ||
338 | static char *rval_card_lookup_return(struct lookup_iterate *iter, snd_config_t *config) | |
339 | { | |
340 | snd_config_t *d; | |
341 | const char *s; | |
342 | ||
343 | if (snd_config_search(config, "return", &d)) | |
344 | return strdup(snd_ctl_card_info_get_id(iter->info)); | |
345 | else if (snd_config_get_string(d, &s)) | |
346 | return NULL; | |
347 | else if (strcasecmp(s, "id") == 0) | |
348 | return strdup(snd_ctl_card_info_get_id(iter->info)); | |
349 | else if (strcasecmp(s, "number") == 0) { | |
350 | char num[16]; | |
351 | snprintf(num, sizeof(num), "%d", snd_ctl_card_info_get_card(iter->info)); | |
352 | return strdup(num); | |
353 | } else { | |
354 | uc_error("Unknown return type '%s'", s); | |
355 | return NULL; | |
356 | } | |
357 | } | |
358 | ||
359 | static char *rval_card_lookup(snd_use_case_mgr_t *uc_mgr, const char *query) | |
360 | { | |
361 | static struct lookup_fcn fcns[] = { | |
362 | { .name = "id", (lookup_fcn_t)snd_ctl_card_info_get_id }, | |
363 | { .name = "driver", (lookup_fcn_t)snd_ctl_card_info_get_driver }, | |
364 | { .name = "name", (lookup_fcn_t)snd_ctl_card_info_get_name }, | |
365 | { .name = "longname", (lookup_fcn_t)snd_ctl_card_info_get_longname }, | |
366 | { .name = "mixername", (lookup_fcn_t)snd_ctl_card_info_get_mixername }, | |
367 | { .name = "components", (lookup_fcn_t)snd_ctl_card_info_get_components }, | |
368 | { 0 }, | |
369 | }; | |
370 | struct lookup_iterate iter = { | |
371 | .first = rval_card_lookup_first, | |
372 | .next = rval_card_lookup_next, | |
373 | .retfcn = rval_card_lookup_return, | |
374 | .fcns = fcns, | |
375 | }; | |
376 | return rval_lookup_main(uc_mgr, query, &iter); | |
377 | } | |
378 | ||
379 | static struct lookup_iterate *rval_pcm_lookup1(struct lookup_iterate *iter, | |
380 | int device) | |
381 | { | |
382 | snd_pcm_info_t *pcminfo; | |
383 | snd_ctl_t *ctl = iter->ctl_list->ctl; | |
384 | int err; | |
385 | ||
386 | next: | |
387 | if (snd_ctl_pcm_next_device(ctl, &device) < 0 || device < 0) | |
388 | return NULL; | |
389 | pcminfo = iter->info; | |
390 | snd_pcm_info_set_device(pcminfo, device); | |
391 | err = snd_ctl_pcm_info(ctl, pcminfo); | |
392 | if (err < 0) { | |
393 | if (err == -ENOENT) | |
394 | goto next; | |
395 | uc_error("Unable to obtain PCM info (device %d)", device); | |
396 | return NULL; | |
397 | } | |
398 | return iter; | |
399 | } | |
400 | ||
401 | static struct lookup_iterate *rval_pcm_lookup_first(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED, | |
402 | struct lookup_iterate *iter) | |
403 | { | |
404 | return rval_pcm_lookup1(iter, -1); | |
405 | } | |
406 | ||
407 | static struct lookup_iterate *rval_pcm_lookup_next(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED, | |
408 | struct lookup_iterate *iter) | |
409 | { | |
410 | return rval_pcm_lookup1(iter, snd_pcm_info_get_device(iter->info)); | |
411 | } | |
412 | ||
413 | static char *rval_pcm_lookup_return(struct lookup_iterate *iter, | |
414 | snd_config_t *config ATTRIBUTE_UNUSED) | |
415 | { | |
416 | char num[16]; | |
417 | snprintf(num, sizeof(num), "%d", snd_pcm_info_get_device(iter->info)); | |
418 | return strdup(num); | |
419 | } | |
420 | ||
421 | static int rval_pcm_lookup_init(struct lookup_iterate *iter, | |
422 | snd_config_t *config) | |
423 | { | |
424 | static struct lookup_fcn pcm_fcns[] = { | |
425 | { .name = "id", (lookup_fcn_t)snd_pcm_info_get_id }, | |
426 | { .name = "name", (lookup_fcn_t)snd_pcm_info_get_name }, | |
427 | { .name = "subname", (lookup_fcn_t)snd_pcm_info_get_subdevice_name }, | |
428 | { 0 }, | |
429 | }; | |
430 | snd_config_t *d; | |
431 | const char *s; | |
432 | snd_pcm_info_t *pcminfo; | |
433 | snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; | |
434 | ||
435 | if (snd_config_search(config, "stream", &d) == 0 && | |
436 | snd_config_get_string(d, &s) == 0) { | |
437 | if (strcasecmp(s, "playback") == 0) | |
438 | stream = SND_PCM_STREAM_PLAYBACK; | |
439 | else if (strcasecmp(s, "capture") == 0) | |
440 | stream = SND_PCM_STREAM_CAPTURE; | |
441 | else { | |
442 | uc_error("Unknown stream type '%s'", s); | |
443 | return -EINVAL; | |
444 | } | |
445 | } | |
446 | if (snd_pcm_info_malloc(&pcminfo)) | |
447 | return -ENOMEM; | |
448 | snd_pcm_info_set_device(pcminfo, 0); | |
449 | snd_pcm_info_set_subdevice(pcminfo, 0); | |
450 | snd_pcm_info_set_stream(pcminfo, stream); | |
451 | iter->first = rval_pcm_lookup_first; | |
452 | iter->next = rval_pcm_lookup_next; | |
453 | iter->retfcn = rval_pcm_lookup_return; | |
454 | iter->fcns = pcm_fcns; | |
455 | iter->info = pcminfo; | |
456 | return 0; | |
457 | } | |
458 | ||
459 | static int rval_device_lookup_init(snd_use_case_mgr_t *uc_mgr, | |
460 | struct lookup_iterate *iter, | |
461 | snd_config_t *config) | |
462 | { | |
463 | static struct { | |
464 | const char *name; | |
465 | int (*init)(struct lookup_iterate *iter, snd_config_t *config); | |
466 | } *t, types[] = { | |
467 | { .name = "pcm", .init = rval_pcm_lookup_init }, | |
468 | { 0 } | |
469 | }; | |
470 | snd_config_t *d; | |
471 | const char *s; | |
472 | int err; | |
473 | ||
474 | if (snd_config_search(config, "ctl", &d) || snd_config_get_string(d, &s)) { | |
475 | iter->ctl_list = uc_mgr_get_master_ctl(uc_mgr); | |
476 | if (iter->ctl_list == NULL) { | |
477 | uc_error("Control device is not defined!"); | |
478 | return -EINVAL; | |
479 | } | |
480 | } else { | |
481 | err = uc_mgr_open_ctl(uc_mgr, &iter->ctl_list, s, 1); | |
482 | if (err < 0) { | |
483 | uc_error("Control device '%s' not found", s); | |
484 | return -EINVAL; | |
485 | } | |
486 | } | |
487 | if (snd_config_search(config, "type", &d) || snd_config_get_string(d, &s)) { | |
488 | uc_error("Missing device type!"); | |
489 | return -EINVAL; | |
490 | } | |
491 | for (t = types; t->name; t++) | |
492 | if (strcasecmp(t->name, s) == 0) | |
493 | return t->init(iter, config); | |
494 | uc_error("Device type '%s' is invalid", s); | |
495 | return -EINVAL; | |
496 | } | |
497 | ||
498 | static void rval_device_lookup_done(struct lookup_iterate *iter) | |
499 | { | |
500 | free(iter->info); | |
501 | } | |
502 | ||
503 | static char *rval_device_lookup(snd_use_case_mgr_t *uc_mgr, const char *query) | |
504 | { | |
505 | struct lookup_iterate iter = { | |
506 | .init = rval_device_lookup_init, | |
507 | .done = rval_device_lookup_done, | |
508 | }; | |
509 | return rval_lookup_main(uc_mgr, query, &iter); | |
179 | 510 | } |
180 | 511 | |
181 | 512 | static char *rval_env(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED, const char *id) |
193 | 524 | char path[PATH_MAX], link[PATH_MAX + 1]; |
194 | 525 | struct stat sb; |
195 | 526 | ssize_t len; |
196 | char *e; | |
527 | const char *e; | |
197 | 528 | int fd; |
198 | 529 | |
199 | e = getenv("SYSFS_PATH"); | |
530 | e = uc_mgr_sysfs_root(); | |
200 | 531 | if (e == NULL) |
201 | e = "/sys"; | |
532 | return NULL; | |
202 | 533 | if (id[0] == '/') |
203 | 534 | id++; |
204 | 535 | snprintf(path, sizeof(path), "%s/%s", e, id); |
269 | 600 | goto __match2; \ |
270 | 601 | } |
271 | 602 | |
603 | /* | |
604 | * skip escaped } character (simple version) | |
605 | */ | |
606 | static inline const char *strchr_with_escape(const char *str, char c) | |
607 | { | |
608 | char *s; | |
609 | ||
610 | while (1) { | |
611 | s = strchr(str, c); | |
612 | if (s && s != str) { | |
613 | if (*(s - 1) == '\\') { | |
614 | str = s + 1; | |
615 | continue; | |
616 | } | |
617 | } | |
618 | return s; | |
619 | } | |
620 | } | |
621 | ||
622 | /* | |
623 | * remove escaped } character (simple version) | |
624 | */ | |
625 | static inline void strncpy_with_escape(char *dst, const char *src, size_t len) | |
626 | { | |
627 | char c; | |
628 | ||
629 | c = *src++; | |
630 | while (c != '\0' && len > 0) { | |
631 | if (c == '\\' && *src == '}') { | |
632 | c = *src++; | |
633 | len--; | |
634 | } | |
635 | *dst++ = c; | |
636 | len--; | |
637 | c = *src++; | |
638 | } | |
639 | *dst = '\0'; | |
640 | } | |
641 | ||
272 | 642 | int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr, |
273 | 643 | char **_rvalue, |
274 | 644 | const char *value) |
275 | 645 | { |
276 | 646 | size_t size, nsize, idsize, rvalsize, dpos = 0; |
277 | 647 | const char *tmp; |
278 | char *r, *nr, *rval, v2[48]; | |
648 | char *r, *nr, *rval, v2[128]; | |
279 | 649 | bool ignore_error, allow_empty; |
280 | 650 | char *(*fcn2)(snd_use_case_mgr_t *, const char *id); |
281 | 651 | int err; |
304 | 674 | } |
305 | 675 | fcn2 = NULL; |
306 | 676 | MATCH_VARIABLE(value, "${OpenName}", rval_open_name, false); |
677 | MATCH_VARIABLE(value, "${ConfLibDir}", rval_conf_libdir, false); | |
307 | 678 | MATCH_VARIABLE(value, "${ConfTopDir}", rval_conf_topdir, false); |
308 | 679 | MATCH_VARIABLE(value, "${ConfDir}", rval_conf_dir, false); |
309 | 680 | MATCH_VARIABLE(value, "${ConfName}", rval_conf_name, false); |
316 | 687 | MATCH_VARIABLE2(value, "${env:", rval_env, false); |
317 | 688 | MATCH_VARIABLE2(value, "${sys:", rval_sysfs, false); |
318 | 689 | MATCH_VARIABLE2(value, "${var:", rval_var, true); |
690 | MATCH_VARIABLE2(value, "${find-card:", rval_card_lookup, false); | |
691 | MATCH_VARIABLE2(value, "${find-device:", rval_device_lookup, false); | |
319 | 692 | MATCH_VARIABLE2(value, "${CardNumberByName:", rval_card_number_by_name, false); |
320 | 693 | MATCH_VARIABLE2(value, "${CardIdByName:", rval_card_id_by_name, false); |
321 | 694 | __merr: |
330 | 703 | } |
331 | 704 | goto __error; |
332 | 705 | __match2: |
333 | tmp = strchr(value + idsize, '}'); | |
706 | tmp = strchr_with_escape(value + idsize, '}'); | |
334 | 707 | if (tmp) { |
335 | 708 | rvalsize = tmp - (value + idsize); |
336 | 709 | if (rvalsize >= sizeof(v2)) { |
337 | 710 | err = -ENOMEM; |
338 | 711 | goto __error; |
339 | 712 | } |
340 | strncpy(v2, value + idsize, rvalsize); | |
341 | v2[rvalsize] = '\0'; | |
713 | strncpy_with_escape(v2, value + idsize, rvalsize); | |
342 | 714 | idsize += rvalsize + 1; |
343 | 715 | if (*v2 == '$' && uc_mgr->conf_format >= 3) { |
344 | 716 | tmp = uc_mgr_get_variable(uc_mgr, v2 + 1); |
416 | 788 | if (err < 0) |
417 | 789 | return err; |
418 | 790 | err = snd_config_set_id(node, s); |
419 | free(s); | |
420 | 791 | if (err < 0) { |
421 | 792 | uc_error("unable to set substituted id '%s' (old id '%s')", s, id); |
793 | free(s); | |
422 | 794 | return err; |
423 | 795 | } |
796 | free(s); | |
424 | 797 | } |
425 | 798 | if (snd_config_get_type(node) != SND_CONFIG_TYPE_COMPOUND) { |
426 | 799 | if (snd_config_get_type(node) == SND_CONFIG_TYPE_STRING) { |
48 | 48 | va_end(va); |
49 | 49 | } |
50 | 50 | |
51 | const char *uc_mgr_sysfs_root(void) | |
52 | { | |
53 | const char *e = getenv("SYSFS_PATH"); | |
54 | if (e == NULL) | |
55 | return "/sys"; | |
56 | if (*e == '\0') | |
57 | uc_error("no sysfs root!"); | |
58 | return e; | |
59 | } | |
60 | ||
51 | 61 | struct ctl_list *uc_mgr_get_master_ctl(snd_use_case_mgr_t *uc_mgr) |
52 | 62 | { |
53 | 63 | struct list_head *pos; |
66 | 76 | return ctl_list; |
67 | 77 | } |
68 | 78 | |
79 | struct ctl_list *uc_mgr_get_ctl_by_card(snd_use_case_mgr_t *uc_mgr, int card) | |
80 | { | |
81 | struct ctl_list *ctl_list; | |
82 | char cname[32]; | |
83 | int err; | |
84 | ||
85 | sprintf(cname, "hw:%d", card); | |
86 | err = uc_mgr_open_ctl(uc_mgr, &ctl_list, cname, 1); | |
87 | if (err < 0) | |
88 | return NULL; | |
89 | return ctl_list; | |
90 | } | |
91 | ||
69 | 92 | struct ctl_list *uc_mgr_get_ctl_by_name(snd_use_case_mgr_t *uc_mgr, const char *name, int idx) |
70 | 93 | { |
71 | 94 | struct list_head *pos; |
72 | struct ctl_list *ctl_list = NULL; | |
95 | struct ctl_list *ctl_list; | |
73 | 96 | const char *s; |
74 | char cname[32]; | |
75 | int idx2, card, err; | |
97 | int idx2, card; | |
76 | 98 | |
77 | 99 | idx2 = idx; |
78 | 100 | list_for_each(pos, &uc_mgr->ctl_list) { |
93 | 115 | return NULL; |
94 | 116 | |
95 | 117 | while (card >= 0) { |
96 | sprintf(cname, "hw:%d", card); | |
97 | err = uc_mgr_open_ctl(uc_mgr, &ctl_list, cname, 1); | |
98 | if (err < 0) | |
118 | ctl_list = uc_mgr_get_ctl_by_card(uc_mgr, card); | |
119 | if (ctl_list == NULL) | |
99 | 120 | continue; /* really? */ |
100 | 121 | s = snd_ctl_card_info_get_name(ctl_list->ctl_info); |
101 | 122 | if (s && strcmp(s, name) == 0) { |
244 | 265 | struct ctl_dev *ctl_dev; |
245 | 266 | snd_ctl_card_info_t *info; |
246 | 267 | const char *id; |
247 | int err, card; | |
268 | int err, card, ucm_group, ucm_offset; | |
248 | 269 | |
249 | 270 | snd_ctl_card_info_alloca(&info); |
271 | ||
272 | ucm_group = _snd_is_ucm_device(device); | |
273 | ucm_offset = ucm_group ? 8 : 0; | |
250 | 274 | |
251 | 275 | /* cache lookup */ |
252 | 276 | list_for_each(pos1, &uc_mgr->ctl_list) { |
253 | 277 | ctl_list = list_entry(pos1, struct ctl_list, list); |
278 | if (ctl_list->ucm_group != ucm_group) | |
279 | continue; | |
254 | 280 | list_for_each(pos2, &ctl_list->dev_list) { |
255 | 281 | ctl_dev = list_entry(pos2, struct ctl_dev, list); |
256 | if (strcmp(ctl_dev->device, device) == 0) { | |
282 | if (strcmp(ctl_dev->device, device + ucm_offset) == 0) { | |
257 | 283 | *ctll = ctl_list; |
258 | 284 | if (!slave) |
259 | 285 | ctl_list->slave = 0; |
279 | 305 | /* insert to cache, if just name differs */ |
280 | 306 | list_for_each(pos1, &uc_mgr->ctl_list) { |
281 | 307 | ctl_list = list_entry(pos1, struct ctl_list, list); |
308 | if (ctl_list->ucm_group != ucm_group) | |
309 | continue; | |
282 | 310 | if (strcmp(id, snd_ctl_card_info_get_id(ctl_list->ctl_info)) == 0) { |
283 | 311 | card = snd_card_get_index(id); |
284 | err = uc_mgr_ctl_add(uc_mgr, &ctl_list, ctl, card, info, device, slave); | |
312 | err = uc_mgr_ctl_add(uc_mgr, &ctl_list, ctl, card, info, device + ucm_offset, slave); | |
285 | 313 | if (err < 0) |
286 | 314 | goto __nomem; |
287 | 315 | snd_ctl_close(ctl); |
316 | ctl_list->ucm_group = ucm_group; | |
288 | 317 | *ctll = ctl_list; |
289 | 318 | return 0; |
290 | 319 | } |
291 | 320 | } |
292 | 321 | |
293 | 322 | ctl_list = NULL; |
294 | err = uc_mgr_ctl_add(uc_mgr, &ctl_list, ctl, -1, info, device, slave); | |
323 | err = uc_mgr_ctl_add(uc_mgr, &ctl_list, ctl, -1, info, device + ucm_offset, slave); | |
295 | 324 | if (err < 0) |
296 | 325 | goto __nomem; |
297 | 326 | |
327 | ctl_list->ucm_group = ucm_group; | |
298 | 328 | *ctll = ctl_list; |
299 | 329 | return 0; |
300 | 330 | |
319 | 349 | return path; |
320 | 350 | } |
321 | 351 | |
322 | int uc_mgr_config_load(int format, const char *file, snd_config_t **cfg) | |
352 | int uc_mgr_config_load_into(int format, const char *file, snd_config_t *top) | |
323 | 353 | { |
324 | 354 | FILE *fp; |
325 | 355 | snd_input_t *in; |
326 | snd_config_t *top; | |
327 | 356 | const char *default_paths[2]; |
328 | 357 | int err; |
329 | 358 | |
330 | 359 | fp = fopen(file, "r"); |
331 | 360 | if (!fp) { |
332 | 361 | err = -errno; |
333 | __err0: | |
362 | __err_open: | |
334 | 363 | uc_error("could not open configuration file %s", file); |
335 | 364 | return err; |
336 | 365 | } |
337 | 366 | err = snd_input_stdio_attach(&in, fp, 1); |
338 | 367 | if (err < 0) |
339 | goto __err0; | |
340 | err = snd_config_top(&top); | |
341 | if (err < 0) | |
342 | goto __err1; | |
368 | goto __err_open; | |
343 | 369 | |
344 | 370 | default_paths[0] = uc_mgr_config_dir(format); |
345 | 371 | default_paths[1] = NULL; |
346 | 372 | err = _snd_config_load_with_include(top, in, 0, default_paths); |
347 | 373 | if (err < 0) { |
348 | 374 | uc_error("could not load configuration file %s", file); |
349 | goto __err2; | |
375 | if (in) | |
376 | snd_input_close(in); | |
377 | return err; | |
350 | 378 | } |
351 | 379 | err = snd_input_close(in); |
380 | if (err < 0) | |
381 | return err; | |
382 | return 0; | |
383 | } | |
384 | ||
385 | int uc_mgr_config_load(int format, const char *file, snd_config_t **cfg) | |
386 | { | |
387 | snd_config_t *top; | |
388 | int err; | |
389 | ||
390 | err = snd_config_top(&top); | |
391 | if (err < 0) | |
392 | return err; | |
393 | err = uc_mgr_config_load_into(format, file, top); | |
352 | 394 | if (err < 0) { |
353 | in = NULL; | |
354 | goto __err2; | |
395 | snd_config_delete(top); | |
396 | return err; | |
355 | 397 | } |
356 | 398 | *cfg = top; |
357 | 399 | return 0; |
358 | ||
359 | __err2: | |
360 | snd_config_delete(top); | |
361 | __err1: | |
362 | if (in) | |
363 | snd_input_close(in); | |
364 | return err; | |
365 | 400 | } |
366 | 401 | |
367 | 402 | void uc_mgr_free_value(struct list_head *base) |
463 | 498 | free(seq->data.cdev); |
464 | 499 | break; |
465 | 500 | case SEQUENCE_ELEMENT_TYPE_CSET: |
501 | case SEQUENCE_ELEMENT_TYPE_CSET_NEW: | |
466 | 502 | case SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE: |
467 | 503 | case SEQUENCE_ELEMENT_TYPE_CSET_TLV: |
504 | case SEQUENCE_ELEMENT_TYPE_CTL_REMOVE: | |
468 | 505 | free(seq->data.cset); |
469 | 506 | break; |
507 | case SEQUENCE_ELEMENT_TYPE_SYSSET: | |
508 | free(seq->data.sysw); | |
509 | break; | |
470 | 510 | case SEQUENCE_ELEMENT_TYPE_EXEC: |
511 | case SEQUENCE_ELEMENT_TYPE_SHELL: | |
471 | 512 | free(seq->data.exec); |
513 | break; | |
514 | case SEQUENCE_ELEMENT_TYPE_CFGSAVE: | |
515 | free(seq->data.cfgsave); | |
472 | 516 | break; |
473 | 517 | default: |
474 | 518 | break; |
680 | 724 | list_del(&verb->list); |
681 | 725 | free(verb); |
682 | 726 | } |
727 | uc_mgr_free_sequence(&uc_mgr->fixedboot_list); | |
683 | 728 | uc_mgr_free_sequence(&uc_mgr->boot_list); |
684 | 729 | uc_mgr_free_sequence(&uc_mgr->default_list); |
685 | 730 | uc_mgr_free_value(&uc_mgr->value_list); |
697 | 742 | |
698 | 743 | void uc_mgr_free(snd_use_case_mgr_t *uc_mgr) |
699 | 744 | { |
745 | snd_config_delete(uc_mgr->local_config); | |
700 | 746 | uc_mgr_free_verb(uc_mgr); |
701 | 747 | uc_mgr_free_ctl_list(uc_mgr); |
702 | 748 | free(uc_mgr->card_name); |
703 | 749 | free(uc_mgr); |
704 | 750 | } |
751 | ||
752 | /* | |
753 | * UCM card list stuff | |
754 | */ | |
755 | ||
756 | static pthread_mutex_t ucm_cards_mutex = PTHREAD_MUTEX_INITIALIZER; | |
757 | static LIST_HEAD(ucm_cards); | |
758 | static unsigned int ucm_card_assign; | |
759 | ||
760 | static snd_use_case_mgr_t *uc_mgr_card_find(unsigned int card_number) | |
761 | { | |
762 | struct list_head *pos; | |
763 | snd_use_case_mgr_t *uc_mgr; | |
764 | ||
765 | list_for_each(pos, &ucm_cards) { | |
766 | uc_mgr = list_entry(pos, snd_use_case_mgr_t, cards_list); | |
767 | if (uc_mgr->ucm_card_number == card_number) | |
768 | return uc_mgr; | |
769 | } | |
770 | return NULL; | |
771 | } | |
772 | ||
773 | int uc_mgr_card_open(snd_use_case_mgr_t *uc_mgr) | |
774 | { | |
775 | unsigned int prev; | |
776 | ||
777 | pthread_mutex_lock(&ucm_cards_mutex); | |
778 | prev = ucm_card_assign++; | |
779 | while (uc_mgr_card_find(ucm_card_assign)) { | |
780 | ucm_card_assign++; | |
781 | ucm_card_assign &= 0xffff; | |
782 | if (ucm_card_assign == prev) { | |
783 | pthread_mutex_unlock(&ucm_cards_mutex); | |
784 | return -ENOMEM; | |
785 | } | |
786 | } | |
787 | uc_mgr->ucm_card_number = ucm_card_assign; | |
788 | list_add(&uc_mgr->cards_list, &ucm_cards); | |
789 | pthread_mutex_unlock(&ucm_cards_mutex); | |
790 | return 0; | |
791 | } | |
792 | ||
793 | void uc_mgr_card_close(snd_use_case_mgr_t *uc_mgr) | |
794 | { | |
795 | pthread_mutex_lock(&ucm_cards_mutex); | |
796 | list_del(&uc_mgr->cards_list); | |
797 | pthread_mutex_unlock(&ucm_cards_mutex); | |
798 | } | |
799 | ||
800 | /** | |
801 | * \brief Get library configuration based on the private ALSA device name | |
802 | * \param name[in] ALSA device name | |
803 | * \retval config A configuration tree or NULL | |
804 | * | |
805 | * The returned configuration (non-NULL) should be unreferenced using | |
806 | * snd_config_unref() call. | |
807 | */ | |
808 | const char *uc_mgr_alibcfg_by_device(snd_config_t **top, const char *name) | |
809 | { | |
810 | char buf[5]; | |
811 | long card_num; | |
812 | snd_config_t *config; | |
813 | snd_use_case_mgr_t *uc_mgr; | |
814 | int err; | |
815 | ||
816 | if (strncmp(name, "_ucm", 4) || strlen(name) < 12 || name[8] != '.') | |
817 | return NULL; | |
818 | strncpy(buf, name + 4, 4); | |
819 | buf[4] = '\0'; | |
820 | err = safe_strtol(buf, &card_num); | |
821 | if (err < 0 || card_num < 0 || card_num > 0xffff) | |
822 | return NULL; | |
823 | config = NULL; | |
824 | pthread_mutex_lock(&ucm_cards_mutex); | |
825 | uc_mgr = uc_mgr_card_find(card_num); | |
826 | /* non-empty configs are accepted only */ | |
827 | if (uc_mgr_has_local_config(uc_mgr)) { | |
828 | config = uc_mgr->local_config; | |
829 | snd_config_ref(config); | |
830 | } | |
831 | pthread_mutex_unlock(&ucm_cards_mutex); | |
832 | if (!config) | |
833 | return NULL; | |
834 | *top = config; | |
835 | return name + 9; | |
836 | } |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
418 | 418 | prefix = @prefix@ |
419 | 419 | program_transform_name = @program_transform_name@ |
420 | 420 | psdir = @psdir@ |
421 | runstatedir = @runstatedir@ | |
421 | 422 | sbindir = @sbindir@ |
422 | 423 | sharedstatedir = @sharedstatedir@ |
423 | 424 | srcdir = @srcdir@ |
18 | 18 | #include <math.h> |
19 | 19 | #include "../include/asoundlib.h" |
20 | 20 | |
21 | static char *command; | |
22 | 21 | static char *pcm_name = "hw:0"; |
23 | 22 | snd_output_t *output = NULL; |
24 | 23 | |
31 | 30 | "-d, --delay add delay \n" |
32 | 31 | "-D, --device=NAME select PCM by name \n" |
33 | 32 | "-p, --playback playback tstamps \n" |
34 | "-t, --ts_type=TYPE Default(0),link(1),link_estimated(2),synchronized(3) \n" | |
33 | "-t, --ts_type=TYPE Compat(0),default(1),link(2),link_absolute(3),link_estimated(4),link_synchronized(5) \n" | |
35 | 34 | "-r, --report show audio timestamp and accuracy validity\n" |
36 | 35 | , command); |
37 | 36 | } |
41 | 40 | { |
42 | 41 | long long nsec; |
43 | 42 | |
44 | nsec = t.tv_sec * 1000000000; | |
43 | nsec = t.tv_sec * 1000000000ULL; | |
45 | 44 | nsec += t.tv_nsec; |
46 | 45 | |
47 | 46 | return nsec; |
148 | 147 | while ((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1) { |
149 | 148 | switch (c) { |
150 | 149 | case 'h': |
151 | usage(command); | |
150 | usage(argv[0]); | |
152 | 151 | return 0; |
153 | 152 | case 'p': |
154 | 153 | do_playback = 1; |
200 | 199 | goto _exit; |
201 | 200 | } |
202 | 201 | |
203 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 0)) | |
202 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT)) | |
204 | 203 | printf("Playback supports audio compat timestamps\n"); |
205 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 1)) | |
204 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT)) | |
206 | 205 | printf("Playback supports audio default timestamps\n"); |
207 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 2)) | |
206 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_LINK)) | |
208 | 207 | printf("Playback supports audio link timestamps\n"); |
209 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 3)) | |
208 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE)) | |
210 | 209 | printf("Playback supports audio link absolute timestamps\n"); |
211 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 4)) | |
210 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED)) | |
212 | 211 | printf("Playback supports audio link estimated timestamps\n"); |
213 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 5)) | |
212 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED)) | |
214 | 213 | printf("Playback supports audio link synchronized timestamps\n"); |
215 | 214 | |
216 | 215 | snd_pcm_sw_params_alloca(&swparams_p); |
268 | 267 | goto _exit; |
269 | 268 | } |
270 | 269 | |
271 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 0)) | |
270 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT)) | |
272 | 271 | printf("Capture supports audio compat timestamps\n"); |
273 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 1)) | |
272 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT)) | |
274 | 273 | printf("Capture supports audio default timestamps\n"); |
275 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 2)) | |
274 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_LINK)) | |
276 | 275 | printf("Capture supports audio link timestamps\n"); |
277 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 3)) | |
276 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE)) | |
278 | 277 | printf("Capture supports audio link absolute timestamps\n"); |
279 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 4)) | |
278 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED)) | |
280 | 279 | printf("Capture supports audio link estimated timestamps\n"); |
281 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 5)) | |
280 | if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED)) | |
282 | 281 | printf("Capture supports audio link synchronized timestamps\n"); |
283 | 282 | |
284 | 283 | snd_pcm_sw_params_alloca(&swparams_c); |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
508 | 508 | prefix = @prefix@ |
509 | 509 | program_transform_name = @program_transform_name@ |
510 | 510 | psdir = @psdir@ |
511 | runstatedir = @runstatedir@ | |
511 | 512 | sbindir = @sbindir@ |
512 | 513 | sharedstatedir = @sharedstatedir@ |
513 | 514 | srcdir = @srcdir@ |
2 | 2 | |
3 | 3 | scriptversion=2018-03-07.03; # UTC |
4 | 4 | |
5 | # Copyright (C) 2011-2018 Free Software Foundation, Inc. | |
5 | # Copyright (C) 2011-2020 Free Software Foundation, Inc. | |
6 | 6 | # |
7 | 7 | # This program is free software; you can redistribute it and/or modify |
8 | 8 | # it under the terms of the GNU General Public License as published by |
0 | # Makefile.in generated by automake 1.16.1 from Makefile.am. | |
0 | # Makefile.in generated by automake 1.16.2 from Makefile.am. | |
1 | 1 | # @configure_input@ |
2 | 2 | |
3 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. | |
3 | # Copyright (C) 1994-2020 Free Software Foundation, Inc. | |
4 | 4 | |
5 | 5 | # This Makefile.in is free software; the Free Software Foundation |
6 | 6 | # gives unlimited permission to copy and/or distribute it, |
276 | 276 | prefix = @prefix@ |
277 | 277 | program_transform_name = @program_transform_name@ |
278 | 278 | psdir = @psdir@ |
279 | runstatedir = @runstatedir@ | |
279 | 280 | sbindir = @sbindir@ |
280 | 281 | sharedstatedir = @sharedstatedir@ |
281 | 282 | srcdir = @srcdir@ |
80 | 80 | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` |
81 | 81 | AC_MSG_RESULT($alsa_min_major_version.$alsa_min_minor_version.$alsa_min_micro_version) |
82 | 82 | |
83 | AC_LANG_SAVE | |
84 | AC_LANG_C | |
83 | AC_LANG_PUSH([C]) | |
85 | 84 | AC_MSG_CHECKING([for libasound headers version >= $alsa_min_major_version.$alsa_min_minor_version.$alsa_min_micro_version ($min_alsa_version)]) |
86 | AC_TRY_COMPILE([ | |
85 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ | |
87 | 86 | #include <alsa/asoundlib.h> |
88 | ], [ | |
87 | ]], [[ | |
89 | 88 | /* ensure backward compatibility */ |
90 | 89 | #if !defined(SND_LIB_MAJOR) && defined(SOUNDLIB_VERSION_MAJOR) |
91 | 90 | #define SND_LIB_MAJOR SOUNDLIB_VERSION_MAJOR |
117 | 116 | # endif |
118 | 117 | # endif |
119 | 118 | exit(0); |
120 | ], | |
119 | ]])], | |
121 | 120 | [AC_MSG_RESULT(found.)], |
122 | 121 | [AC_MSG_RESULT(not present.) |
123 | 122 | ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libasound not found.)]) |
124 | 123 | alsa_found=no] |
125 | 124 | ) |
126 | AC_LANG_RESTORE | |
127 | ||
128 | AC_LANG_SAVE | |
129 | AC_LANG_C | |
125 | AC_LANG_POP([C]) | |
126 | ||
127 | AC_LANG_PUSH([C]) | |
130 | 128 | AC_MSG_CHECKING([for libatopology (sound headers version > 1.1.9)]) |
131 | AC_TRY_COMPILE([ | |
129 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ | |
132 | 130 | #include <alsa/asoundlib.h> |
133 | 131 | #include <alsa/topology.h> |
134 | ], [ | |
132 | ]], [[ | |
135 | 133 | /* ensure backward compatibility */ |
136 | 134 | #if !defined(SND_LIB_VERSION) |
137 | 135 | #define SND_LIB_VERSION 0 |
142 | 140 | # error not present |
143 | 141 | #endif |
144 | 142 | exit(0); |
145 | ], | |
143 | ]])], | |
146 | 144 | [AC_MSG_RESULT(yes) |
147 | 145 | enable_atopology="yes"], |
148 | 146 | [AC_MSG_RESULT(no)] |
149 | 147 | ) |
150 | AC_LANG_RESTORE | |
151 | ||
148 | AC_LANG_POP([C]) | |
152 | 149 | fi |
153 | 150 | |
154 | 151 | dnl Now that we know that we have the right version, let's see if we have the library and not just the headers. |