diff --git a/0010-remove-unnecessary-obsolete-compat-hsearch_r.c.patch b/0010-remove-unnecessary-obsolete-compat-hsearch_r.c.patch
new file mode 100644
index 0000000..97fd685
--- /dev/null
+++ b/0010-remove-unnecessary-obsolete-compat-hsearch_r.c.patch
@@ -0,0 +1,334 @@
+From c1fbd57c38dd565d3f87219031658f676654484f Mon Sep 17 00:00:00 2001
+From: Waldemar Brodkorb
+Date: Wed, 2 Oct 2013 21:00:51 +0200
+Subject: [PATCH] remove unnecessary/obsolete compat/hsearch_r.c
+
+The usage of hsearch functions where removed long time
+ago in commit 273d115de05574251bdd661747ecb68449a5cf1d.
+This patch highly increases portability for non-glibc systems.
+
+Remove the complete compat directory as requested by
+Takashi Iwai.
+
+Signed-off-by: Waldemar Brodkorb
+Signed-off-by: Takashi Iwai
+---
+ configure.in | 4 +-
+ src/Makefile.am | 7 +-
+ src/compat/Makefile.am | 8 --
+ src/compat/empty.c | 0
+ src/compat/hsearch_r.c | 236 -------------------------------------------------
+ 5 files changed, 3 insertions(+), 252 deletions(-)
+ delete mode 100644 src/compat/Makefile.am
+ delete mode 100644 src/compat/empty.c
+ delete mode 100644 src/compat/hsearch_r.c
+
+diff --git a/configure.in b/configure.in
+index 00fff2b8da97..35fd89fc298a 100644
+--- a/configure.in
++++ b/configure.in
+@@ -64,8 +64,6 @@ AC_HEADER_TIME
+
+ dnl Checks for library functions.
+ AC_PROG_GCC_TRADITIONAL
+-AC_CHECK_FUNC([hsearch_r], [HAVE_HSEARCH_R=yes])
+-AM_CONDITIONAL([ALSA_HSEARCH_R], [test "x$HAVE_HSEARCH_R" != xyes])
+ AC_CHECK_FUNCS([uselocale])
+
+ SAVE_LIBRARY_VERSION
+@@ -659,7 +657,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \
+ src/pcm/Makefile src/pcm/scopes/Makefile \
+ src/rawmidi/Makefile src/timer/Makefile \
+ src/hwdep/Makefile src/seq/Makefile src/ucm/Makefile \
+- src/compat/Makefile src/alisp/Makefile \
++ src/alisp/Makefile \
+ src/conf/Makefile src/conf/alsa.conf.d/Makefile \
+ src/conf/cards/Makefile \
+ src/conf/pcm/Makefile \
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 08f482adc0d3..8f789fecc125 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -46,8 +46,8 @@ if BUILD_ALISP
+ SUBDIRS += alisp
+ libasound_la_LIBADD += alisp/libalisp.la
+ endif
+-SUBDIRS += compat conf
+-libasound_la_LIBADD += compat/libcompat.la @ALSA_DEPLIBS@
++SUBDIRS += conf
++libasound_la_LIBADD += @ALSA_DEPLIBS@
+
+ libasound_la_LDFLAGS = -version-info $(COMPATNUM) $(VSYMS) $(SYMFUNCS) $(LDFLAGS_NOUNDEFINED)
+
+@@ -84,9 +84,6 @@ ucm/libucm.la:
+ instr/libinstr.la:
+ $(MAKE) -C instr libinstr.la
+
+-compat/libcompat.la:
+- $(MAKE) -C compat libcompat.la
+-
+ alisp/libalisp.la:
+ $(MAKE) -C alisp libalisp.la
+
+diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am
+deleted file mode 100644
+index 01f54fc14b86..000000000000
+--- a/src/compat/Makefile.am
++++ /dev/null
+@@ -1,8 +0,0 @@
+-noinst_LTLIBRARIES = libcompat.la
+-EXTRA_libcompat_la_SOURCES = hsearch_r.c
+-
+-if ALSA_HSEARCH_R
+-libcompat_la_SOURCES = empty.c hsearch_r.c
+-else
+-libcompat_la_SOURCES = empty.c
+-endif
+diff --git a/src/compat/empty.c b/src/compat/empty.c
+deleted file mode 100644
+index e69de29bb2d1..000000000000
+diff --git a/src/compat/hsearch_r.c b/src/compat/hsearch_r.c
+deleted file mode 100644
+index 96ceac10c011..000000000000
+--- a/src/compat/hsearch_r.c
++++ /dev/null
+@@ -1,236 +0,0 @@
+-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+- This file is part of the GNU C Library.
+- Contributed by Ulrich Drepper , 1993.
+-
+- The GNU C Library is free software; you can redistribute it and/or
+- modify it under the terms of the GNU Lesser General Public License as
+- published by the Free Software Foundation; either version 2.1 of the
+- License, or (at your option) any later version.
+-
+- The GNU C Library is distributed in the hope that it will be useful,
+- but WITHOUT ANY WARRANTY; without even the implied warranty of
+- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+- Lesser General Public License for more details.
+-
+- You should have received a copy of the GNU Lesser General Public
+- License along with the GNU C Library; see the file COPYING.LIB. If not,
+- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+- Boston, MA 02111-1307, USA. */
+-
+-#include
+-#include
+-#include
+-
+-#define __USE_GNU
+-#ifndef __set_errno
+-#define __set_errno(e) errno = (e)
+-#endif
+-#include
+-
+-/* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
+- [Knuth] The Art of Computer Programming, part 3 (6.4) */
+-
+-
+-/* The reentrant version has no static variables to maintain the state.
+- Instead the interface of all functions is extended to take an argument
+- which describes the current status. */
+-typedef struct _ENTRY
+-{
+- unsigned int used;
+- ENTRY entry;
+-}
+-_ENTRY;
+-
+-
+-/* For the used double hash method the table size has to be a prime. To
+- correct the user given table size we need a prime test. This trivial
+- algorithm is adequate because
+- a) the code is (most probably) called a few times per program run and
+- b) the number is small because the table must fit in the core */
+-static int
+-isprime (unsigned int number)
+-{
+- /* no even number will be passed */
+- unsigned int div = 3;
+-
+- while (div * div < number && number % div != 0)
+- div += 2;
+-
+- return number % div != 0;
+-}
+-
+-
+-/* Before using the hash table we must allocate memory for it.
+- Test for an existing table are done. We allocate one element
+- more as the found prime number says. This is done for more effective
+- indexing as explained in the comment for the hsearch function.
+- The contents of the table is zeroed, especially the field used
+- becomes zero. */
+-int
+-hcreate_r (nel, htab)
+- size_t nel;
+- struct hsearch_data *htab;
+-{
+- /* Test for correct arguments. */
+- if (htab == NULL)
+- {
+- __set_errno (EINVAL);
+- return 0;
+- }
+-
+- /* There is still another table active. Return with error. */
+- if (htab->table != NULL)
+- return 0;
+-
+- /* Change nel to the first prime number not smaller as nel. */
+- nel |= 1; /* make odd */
+- while (!isprime (nel))
+- nel += 2;
+-
+- htab->size = nel;
+- htab->filled = 0;
+-
+- /* allocate memory and zero out */
+- htab->table = (_ENTRY *) calloc (htab->size + 1, sizeof (_ENTRY));
+- if (htab->table == NULL)
+- return 0;
+-
+- /* everything went alright */
+- return 1;
+-}
+-
+-
+-/* After using the hash table it has to be destroyed. The used memory can
+- be freed and the local static variable can be marked as not used. */
+-void
+-hdestroy_r (htab)
+- struct hsearch_data *htab;
+-{
+- /* Test for correct arguments. */
+- if (htab == NULL)
+- {
+- __set_errno (EINVAL);
+- return;
+- }
+-
+- if (htab->table != NULL)
+- /* free used memory */
+- free (htab->table);
+-
+- /* the sign for an existing table is an value != NULL in htable */
+- htab->table = NULL;
+-}
+-
+-
+-/* This is the search function. It uses double hashing with open addressing.
+- The argument item.key has to be a pointer to an zero terminated, most
+- probably strings of chars. The function for generating a number of the
+- strings is simple but fast. It can be replaced by a more complex function
+- like ajw (see [Aho,Sethi,Ullman]) if the needs are shown.
+-
+- We use an trick to speed up the lookup. The table is created by hcreate
+- with one more element available. This enables us to use the index zero
+- special. This index will never be used because we store the first hash
+- index in the field used where zero means not used. Every other value
+- means used. The used field can be used as a first fast comparison for
+- equality of the stored and the parameter value. This helps to prevent
+- unnecessary expensive calls of strcmp. */
+-int
+-hsearch_r (item, action, retval, htab)
+- ENTRY item;
+- ACTION action;
+- ENTRY **retval;
+- struct hsearch_data *htab;
+-{
+- unsigned int hval;
+- unsigned int count;
+- unsigned int len = strlen (item.key);
+- unsigned int idx;
+-
+- /* Compute an value for the given string. Perhaps use a better method. */
+- hval = len;
+- count = len;
+- while (count-- > 0)
+- {
+- hval <<= 4;
+- hval += item.key[count];
+- }
+-
+- /* First hash function: simply take the modulo but prevent zero. */
+- hval %= htab->size;
+- if (hval == 0)
+- ++hval;
+-
+- /* The first index tried. */
+- idx = hval;
+-
+- if (htab->table[idx].used)
+- {
+- /* Further action might be required according to the action value. */
+- unsigned hval2;
+-
+- if (htab->table[idx].used == hval
+- && strcmp (item.key, htab->table[idx].entry.key) == 0)
+- {
+- if (action == ENTER)
+- htab->table[idx].entry.data = item.data;
+-
+- *retval = &htab->table[idx].entry;
+- return 1;
+- }
+-
+- /* Second hash function, as suggested in [Knuth] */
+- hval2 = 1 + hval % (htab->size - 2);
+-
+- do
+- {
+- /* Because SIZE is prime this guarantees to step through all
+- available indexes. */
+- if (idx <= hval2)
+- idx = htab->size + idx - hval2;
+- else
+- idx -= hval2;
+-
+- /* If we visited all entries leave the loop unsuccessfully. */
+- if (idx == hval)
+- break;
+-
+- /* If entry is found use it. */
+- if (htab->table[idx].used == hval
+- && strcmp (item.key, htab->table[idx].entry.key) == 0)
+- {
+- if (action == ENTER)
+- htab->table[idx].entry.data = item.data;
+-
+- *retval = &htab->table[idx].entry;
+- return 1;
+- }
+- }
+- while (htab->table[idx].used);
+- }
+-
+- /* An empty bucket has been found. */
+- if (action == ENTER)
+- {
+- /* If table is full and another entry should be entered return
+- with error. */
+- if (action == ENTER && htab->filled == htab->size)
+- {
+- __set_errno (ENOMEM);
+- *retval = NULL;
+- return 0;
+- }
+-
+- htab->table[idx].used = hval;
+- htab->table[idx].entry = item;
+-
+- ++htab->filled;
+-
+- *retval = &htab->table[idx].entry;
+- return 1;
+- }
+-
+- __set_errno (ESRCH);
+- *retval = NULL;
+- return 0;
+-}
+--
+1.8.4.3
+
diff --git a/0011-local.h-include-sys-types.h-to-fix-issues-with-pcm.h.patch b/0011-local.h-include-sys-types.h-to-fix-issues-with-pcm.h.patch
new file mode 100644
index 0000000..e759bb8
--- /dev/null
+++ b/0011-local.h-include-sys-types.h-to-fix-issues-with-pcm.h.patch
@@ -0,0 +1,30 @@
+From 10ecf963ca9ee7c491affadd4838ef8e35823d2c Mon Sep 17 00:00:00 2001
+From: John Spencer
+Date: Thu, 10 Oct 2013 18:56:22 +0200
+Subject: [PATCH] local.h: include sys/types.h to fix issues with pcm.h
+
+sys/types.h is required for the u_int_XX types used by pcm.h.
+since a change in pcm.h is not desired, we add the inclusion
+to the header that includes pcm.h during build.
+
+Signed-off-by: John Spencer
+Signed-off-by: Takashi Iwai
+---
+ include/local.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/local.h b/include/local.h
+index f0db188ee580..9464efa49642 100644
+--- a/include/local.h
++++ b/include/local.h
+@@ -31,6 +31,7 @@
+ #include
+ #include
+ #include
++#include
+ #include
+ #include
+ #include
+--
+1.8.4.3
+
diff --git a/0012-test-chmap-Add-missing-usage-text-for-s-option.patch b/0012-test-chmap-Add-missing-usage-text-for-s-option.patch
new file mode 100644
index 0000000..a082eeb
--- /dev/null
+++ b/0012-test-chmap-Add-missing-usage-text-for-s-option.patch
@@ -0,0 +1,25 @@
+From 2d6eb4e9ba1503e094d8cdc30a5a081fd22c1c84 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai
+Date: Mon, 4 Nov 2013 14:19:03 +0100
+Subject: [PATCH] test/chmap: Add missing usage text for -s option
+
+Signed-off-by: Takashi Iwai
+---
+ test/chmap.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/test/chmap.c b/test/chmap.c
+index d73ae7361498..ad3b305b501c 100644
+--- a/test/chmap.c
++++ b/test/chmap.c
+@@ -16,6 +16,7 @@ static void usage(void)
+ " chmap [options] set CH0 CH1 CH2...\n"
+ "options:\n"
+ " -D device Specify PCM device to handle\n"
++ " -s stream Specify PCM stream direction (playback/capture)\n"
+ " -f format PCM format\n"
+ " -c channels Channels\n"
+ " -r rate Sample rate\n");
+--
+1.8.4.3
+
diff --git a/0013-include-global.h-don-t-define-timeval-and-timespec-s.patch b/0013-include-global.h-don-t-define-timeval-and-timespec-s.patch
new file mode 100644
index 0000000..5d969a1
--- /dev/null
+++ b/0013-include-global.h-don-t-define-timeval-and-timespec-s.patch
@@ -0,0 +1,36 @@
+From 7d06b3ed9fda0220c2863ee20acd10c32cf313fd Mon Sep 17 00:00:00 2001
+From: Jaroslav Kysela
+Date: Fri, 8 Nov 2013 12:30:04 +0100
+Subject: [PATCH] include/global.h - don't define timeval and timespec
+ structures for !glibc
+
+On request from John Spencer .
+
+Signed-off-by: Jaroslav Kysela
+---
+ include/global.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/global.h b/include/global.h
+index 3e3680fb698c..16a26dc83518 100644
+--- a/include/global.h
++++ b/include/global.h
+@@ -133,6 +133,7 @@ int snd_shm_area_destroy(struct snd_shm_area *area);
+
+ int snd_user_file(const char *file, char **result);
+
++#ifdef __GLIBC__
+ #if !defined(_POSIX_C_SOURCE) && !defined(_POSIX_SOURCE)
+ struct timeval {
+ time_t tv_sec; /* seconds */
+@@ -144,6 +145,7 @@ struct timespec {
+ long tv_nsec; /* nanoseconds */
+ };
+ #endif
++#endif
+
+ /** Timestamp */
+ typedef struct timeval snd_timestamp_t;
+--
+1.8.4.3
+
diff --git a/0014-conf.c-use-portable-way-to-initialize-recursive-mute.patch b/0014-conf.c-use-portable-way-to-initialize-recursive-mute.patch
new file mode 100644
index 0000000..fa5b41b
--- /dev/null
+++ b/0014-conf.c-use-portable-way-to-initialize-recursive-mute.patch
@@ -0,0 +1,63 @@
+From ae035b7fe5620fcaf4f5ea33ecabcf93b8e056cd Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?=
+Date: Fri, 8 Nov 2013 13:17:58 +0100
+Subject: [PATCH] conf.c: use portable way to initialize recursive mutex
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP is not in POSIX, as _NP
+(non-portable) suggests.
+
+exposing such a symbol in musl libc would lock in the ABI for all
+times and makes it impossible to do future changes to the under-
+lying struct without hideous symbol versioning hacks.
+
+use the portable way instead: pthread_once was designed for such
+cases.
+
+Signed-off-by: Timo Teräs
+Tested-by: John Spencer
+Signed-off-by: Jaroslav Kysela
+---
+ src/conf.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/src/conf.c b/src/conf.c
+index bfed1c434cab..5ccc8e1a53e5 100644
+--- a/src/conf.c
++++ b/src/conf.c
+@@ -427,8 +427,8 @@ beginning:
+ #ifndef DOC_HIDDEN
+
+ #ifdef HAVE_LIBPTHREAD
+-static pthread_mutex_t snd_config_update_mutex =
+- PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
++static pthread_mutex_t snd_config_update_mutex;
++static pthread_once_t snd_config_update_mutex_once = PTHREAD_ONCE_INIT;
+ #endif
+
+ struct _snd_config {
+@@ -472,8 +472,19 @@ typedef struct {
+
+ #ifdef HAVE_LIBPTHREAD
+
++static void snd_config_init_mutex(void)
++{
++ pthread_mutexattr_t attr;
++
++ pthread_mutexattr_init(&attr);
++ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
++ pthread_mutex_init(&snd_config_update_mutex, &attr);
++ pthread_mutexattr_destroy(&attr);
++}
++
+ static inline void snd_config_lock(void)
+ {
++ pthread_once(&snd_config_update_mutex_once, snd_config_init_mutex);
+ pthread_mutex_lock(&snd_config_update_mutex);
+ }
+
+--
+1.8.4.3
+
diff --git a/0015-pcm_file-fix-SEGFAULT-if-file-option-is-missing-whil.patch b/0015-pcm_file-fix-SEGFAULT-if-file-option-is-missing-whil.patch
new file mode 100644
index 0000000..f08da91
--- /dev/null
+++ b/0015-pcm_file-fix-SEGFAULT-if-file-option-is-missing-whil.patch
@@ -0,0 +1,36 @@
+From 1919ee473d9bc6983f11327aef3ae76e923f41be Mon Sep 17 00:00:00 2001
+From: Andrey Mazo
+Date: Sun, 17 Nov 2013 01:11:54 +0400
+Subject: [PATCH] pcm_file: fix SEGFAULT if file option is missing while infile
+ is not.
+
+Commit 5c5f1358123af69155267463a0b6254ad9cbecc4 requires both file and
+infile options to be missing to report a failure.
+In fact, only file option is mandatory and should be checked there.
+Otherwise, NULL file triggers segfault in
+snd_pcm_file_replace_fname() called from
+snd_pcm_file_open_output_file().
+infile option is optional, so don't report fatal error if it's missing.
+
+Signed-off-by: Andrey Mazo
+Signed-off-by: Takashi Iwai
+---
+ src/pcm/pcm_file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
+index 59504019d557..3d14090fd2ea 100644
+--- a/src/pcm/pcm_file.c
++++ b/src/pcm/pcm_file.c
+@@ -948,7 +948,7 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
+ err = snd_pcm_slave_conf(root, slave, &sconf, 0);
+ if (err < 0)
+ return err;
+- if ((!fname || strlen(fname) == 0) && fd < 0 && !ifname) {
++ if ((!fname || strlen(fname) == 0) && fd < 0) {
+ snd_config_delete(sconf);
+ SNDERR("file is not defined");
+ return -EINVAL;
+--
+1.8.4.3
+
diff --git a/0016-pcm_file-fixed-memory-leak.patch b/0016-pcm_file-fixed-memory-leak.patch
new file mode 100644
index 0000000..7a74ebc
--- /dev/null
+++ b/0016-pcm_file-fixed-memory-leak.patch
@@ -0,0 +1,44 @@
+From e017c5f2df386c7c1f221a2f01c80edeec04b253 Mon Sep 17 00:00:00 2001
+From: Andrey Mazo
+Date: Sun, 17 Nov 2013 01:11:55 +0400
+Subject: [PATCH] pcm_file: fixed memory leak.
+
+Valgrind report for this leak was:
+
+Command: aplay -Dfile:'/tmp/qqq',raw qqq.wav
+
+14 bytes in 1 blocks are definitely lost in loss record 1 of 2
+ at 0x402BF5C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
+ by 0x40D7557: snd_pcm_file_hw_params (in /usr/lib/libasound.so.2.0.0)
+ by 0x40BA093: _snd_pcm_hw_params_internal (in /usr/lib/libasound.so.2.0.0)
+ by 0x40AB831: snd_pcm_hw_params (in /usr/lib/libasound.so.2.0.0)
+ by 0x804C523: ??? (in /usr/bin/aplay)
+ by 0x804E5B7: ??? (in /usr/bin/aplay)
+ by 0x804FC8C: ??? (in /usr/bin/aplay)
+ by 0x80520FB: ??? (in /usr/bin/aplay)
+ by 0x4184942: (below main) (libc-start.c:226)
+
+Signed-off-by: Andrey Mazo
+Signed-off-by: Takashi Iwai
+---
+ src/pcm/pcm_file.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
+index 3d14090fd2ea..c3e67b2b2638 100644
+--- a/src/pcm/pcm_file.c
++++ b/src/pcm/pcm_file.c
+@@ -592,8 +592,10 @@ static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
+ snd_pcm_file_t *file = pcm->private_data;
+ free(file->wbuf);
+ free(file->wbuf_areas);
++ free(file->final_fname);
+ file->wbuf = NULL;
+ file->wbuf_areas = NULL;
++ file->final_fname = NULL;
+ return snd_pcm_hw_free(file->gen.slave);
+ }
+
+--
+1.8.4.3
+
diff --git a/0017-pcm_file-don-t-touch-infile-on-playback-and-output-f.patch b/0017-pcm_file-don-t-touch-infile-on-playback-and-output-f.patch
new file mode 100644
index 0000000..a7a82d7
--- /dev/null
+++ b/0017-pcm_file-don-t-touch-infile-on-playback-and-output-f.patch
@@ -0,0 +1,139 @@
+From 4081be0b87ab9fa53a8906e66bc240f18a7a9a54 Mon Sep 17 00:00:00 2001
+From: Andrey Mazo
+Date: Sun, 17 Nov 2013 01:11:56 +0400
+Subject: [PATCH] pcm_file: don't touch infile on playback and output file on
+ capture.
+
+Commit 1d80c5b901baf7e1b7998dfa518532fbd64e4283 message describes
+behaviour in case of specified infile option as
+'No file writes will take place in this case'.
+But this is clearly not the case as output file gets truncated while
+running `arecord -Dtestin >/dev/null`, where "testin" is defined as
+pcm.testin {
+ type file
+ slave.pcm null
+ file "/tmp/qqqq.out"
+ infile "/tmp/qqqq.in"
+ format "raw"
+}
+
+Besides that, the existing behaviour is rather counterintuitive,
+requiring both output and input files to exist and making access to them
+regardless of playback or capture intention.
+Also, it's very confusing to get output file truncated while trying to
+just capture from the device.
+
+Current changeset introduces the following behaviour:
+ - output file ("file" option) is only (p)open()'ed for writing
+ only on playback to the device
+ - any data is written to the output file descriptor
+ (provided with "file" option) only on playback to the device
+ - input file ("infile" option) is only open()'ed for reading only on
+ capture from the device
+ - any data is read from the input file descriptor
+ (provided with the "infile" option) only on capture from the device
+
+Signed-off-by: Andrey Mazo
+Signed-off-by: Takashi Iwai
+---
+ src/pcm/pcm_file.c | 22 +++++++++-------------
+ 1 file changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
+index c3e67b2b2638..25055d0d24cf 100644
+--- a/src/pcm/pcm_file.c
++++ b/src/pcm/pcm_file.c
+@@ -406,7 +406,9 @@ static int snd_pcm_file_close(snd_pcm_t *pcm)
+ if (file->wav_header.fmt)
+ fixup_wav_header(pcm);
+ free((void *)file->fname);
+- close(file->fd);
++ if (file->fd >= 0) {
++ close(file->fd);
++ }
+ }
+ if (file->ifname) {
+ free((void *)file->ifname);
+@@ -533,7 +535,6 @@ static snd_pcm_sframes_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, snd_pc
+ static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
+ {
+ snd_pcm_file_t *file = pcm->private_data;
+- snd_pcm_channel_area_t areas[pcm->channels];
+ snd_pcm_sframes_t n;
+
+ n = snd_pcm_readi(file->gen.slave, buffer, size);
+@@ -545,15 +546,12 @@ static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pc
+ return n;
+ return n * 8 / pcm->frame_bits;
+ }
+- snd_pcm_areas_from_buf(pcm, areas, buffer);
+- snd_pcm_file_add_frames(pcm, areas, 0, n);
+ return n;
+ }
+
+ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
+ {
+ snd_pcm_file_t *file = pcm->private_data;
+- snd_pcm_channel_area_t areas[pcm->channels];
+ snd_pcm_sframes_t n;
+
+ if (file->ifd >= 0) {
+@@ -562,10 +560,6 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm
+ }
+
+ n = snd_pcm_readn(file->gen.slave, bufs, size);
+- if (n > 0) {
+- snd_pcm_areas_from_bufs(pcm, areas, bufs);
+- snd_pcm_file_add_frames(pcm, areas, 0, n);
+- }
+ return n;
+ }
+
+@@ -629,7 +623,7 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
+ a->first = slave->sample_bits * channel;
+ a->step = slave->frame_bits;
+ }
+- if (file->fd < 0) {
++ if ((file->fd < 0) && (pcm->stream == SND_PCM_STREAM_PLAYBACK)) {
+ err = snd_pcm_file_open_output_file(file);
+ if (err < 0) {
+ SYSERR("failed opening output file %s", file->fname);
+@@ -728,7 +722,8 @@ static const snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
+ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
+ const char *fname, int fd, const char *ifname, int ifd,
+ int trunc,
+- const char *fmt, int perm, snd_pcm_t *slave, int close_slave)
++ const char *fmt, int perm, snd_pcm_t *slave, int close_slave,
++ snd_pcm_stream_t stream)
+ {
+ snd_pcm_t *pcm;
+ snd_pcm_file_t *file;
+@@ -758,7 +753,7 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
+ file->trunc = trunc;
+ file->perm = perm;
+
+- if (ifname) {
++ if (ifname && (stream == SND_PCM_STREAM_CAPTURE)) {
+ ifd = open(ifname, O_RDONLY); /* TODO: mind blocking mode */
+ if (ifd < 0) {
+ SYSERR("open %s for reading failed", ifname);
+@@ -790,6 +785,7 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
+ #else
+ pcm->monotonic = 0;
+ #endif
++ pcm->stream = stream;
+ snd_pcm_link_hw_ptr(pcm, slave);
+ snd_pcm_link_appl_ptr(pcm, slave);
+ *pcmp = pcm;
+@@ -960,7 +956,7 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
+ if (err < 0)
+ return err;
+ err = snd_pcm_file_open(pcmp, name, fname, fd, ifname, ifd,
+- trunc, format, perm, spcm, 1);
++ trunc, format, perm, spcm, 1, stream);
+ if (err < 0)
+ snd_pcm_close(spcm);
+ return err;
+--
+1.8.4.3
+
diff --git a/0018-pcm_file-document-new-argument-to-snd_pcm_file_open.patch b/0018-pcm_file-document-new-argument-to-snd_pcm_file_open.patch
new file mode 100644
index 0000000..ed2ae91
--- /dev/null
+++ b/0018-pcm_file-document-new-argument-to-snd_pcm_file_open.patch
@@ -0,0 +1,29 @@
+From 29d89ba0452e29830ca6cd34636aecf160a94a9d Mon Sep 17 00:00:00 2001
+From: Andrey Mazo
+Date: Sun, 17 Nov 2013 19:45:19 +0400
+Subject: [PATCH] pcm_file: document new argument to snd_pcm_file_open().
+
+Document function argument, added in commit
+4081be0b87ab9fa53a8906e66bc240f18a7a9a54.
+
+Signed-off-by: Andrey Mazo
+Signed-off-by: Takashi Iwai
+---
+ src/pcm/pcm_file.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
+index 25055d0d24cf..712302598a9f 100644
+--- a/src/pcm/pcm_file.c
++++ b/src/pcm/pcm_file.c
+@@ -714,6 +714,7 @@ static const snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
+ * \param perm File permission
+ * \param slave Slave PCM handle
+ * \param close_slave When set, the slave PCM handle is closed with copy PCM
++ * \param stream the direction of PCM stream
+ * \retval zero on success otherwise a negative error code
+ * \warning Using of this function might be dangerous in the sense
+ * of compatibility reasons. The prototype might be freely
+--
+1.8.4.3
+
diff --git a/0019-dmix-Don-t-use-assert-and-abort.patch b/0019-dmix-Don-t-use-assert-and-abort.patch
new file mode 100644
index 0000000..0b99650
--- /dev/null
+++ b/0019-dmix-Don-t-use-assert-and-abort.patch
@@ -0,0 +1,32 @@
+From 49ad6699e68862ef9888bdf10b5bdaa19933f1ea Mon Sep 17 00:00:00 2001
+From: Takashi Iwai
+Date: Wed, 27 Nov 2013 09:37:54 +0100
+Subject: [PATCH] dmix: Don't use assert() and abort()
+
+We seem to still have some races at closing a dmix stream, but
+aborting is the worst option. Let's make not melt down.
+
+Reference: https://bugzilla.novell.com/show_bug.cgi?id=852446
+Signed-off-by: Takashi Iwai
+---
+ src/pcm/pcm_direct.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h
+index 70c2c6a0229f..5ae39c0e4237 100644
+--- a/src/pcm/pcm_direct.h
++++ b/src/pcm/pcm_direct.h
+@@ -274,8 +274,8 @@ static inline int snd_pcm_direct_semaphore_up(snd_pcm_direct_t *dmix, int sem_nu
+ static inline int snd_pcm_direct_semaphore_final(snd_pcm_direct_t *dmix, int sem_num)
+ {
+ if (dmix->locked[sem_num] != 1) {
+- assert(dmix->locked[sem_num] != 1);
+- abort();
++ SNDMSG("invalid semaphore count to finalize %d: %d", sem_num, dmix->locked[sem_num]);
++ return -EBUSY;
+ }
+ return snd_pcm_direct_semaphore_up(dmix, sem_num);
+ }
+--
+1.8.4.3
+
diff --git a/alsa.changes b/alsa.changes
index 12bc97e..fb7df12 100644
--- a/alsa.changes
+++ b/alsa.changes
@@ -1,3 +1,22 @@
+-------------------------------------------------------------------
+Wed Nov 27 09:45:38 CET 2013 - tiwai@suse.de
+
+- Backport upstream fixes: cleanups, non-glibc build fixes, fixes
+ and enhancements of pcm_file plugin, etc.
+ 0010-remove-unnecessary-obsolete-compat-hsearch_r.c.patch
+ 0011-local.h-include-sys-types.h-to-fix-issues-with-pcm.h.patch
+ 0012-test-chmap-Add-missing-usage-text-for-s-option.patch
+ 0013-include-global.h-don-t-define-timeval-and-timespec-s.patch
+ 0014-conf.c-use-portable-way-to-initialize-recursive-mute.patch
+ 0015-pcm_file-fix-SEGFAULT-if-file-option-is-missing-whil.patch
+ 0016-pcm_file-fixed-memory-leak.patch
+ 0017-pcm_file-don-t-touch-infile-on-playback-and-output-f.patch
+ 0018-pcm_file-document-new-argument-to-snd_pcm_file_open.patch
+- Fix aborting in races at closing dmix streams (bnc#852446):
+ 0019-dmix-Don-t-use-assert-and-abort.patch
+- Don't include modprobe.d hack for 12.2 and older distros, which
+ seem broken on them
+
-------------------------------------------------------------------
Tue Oct 1 12:27:25 CEST 2013 - tiwai@suse.de
diff --git a/alsa.spec b/alsa.spec
index e6fd16e..98eaf86 100644
--- a/alsa.spec
+++ b/alsa.spec
@@ -63,6 +63,16 @@ Patch6: 0006-Update-iatomic.h-functions-definitions-for-mips.patch
Patch7: 0007-Fix-access-of-freed-memory-in-namehints.patch
Patch8: 0008-HDA-Intel-present-up-to-8-HDMI-DP-outputs-via-hdmi-d.patch
Patch9: 0009-snd_tlv_convert_from_dB-fix-decreasing-gain-across-e.patch
+Patch10: 0010-remove-unnecessary-obsolete-compat-hsearch_r.c.patch
+Patch11: 0011-local.h-include-sys-types.h-to-fix-issues-with-pcm.h.patch
+Patch12: 0012-test-chmap-Add-missing-usage-text-for-s-option.patch
+Patch13: 0013-include-global.h-don-t-define-timeval-and-timespec-s.patch
+Patch14: 0014-conf.c-use-portable-way-to-initialize-recursive-mute.patch
+Patch15: 0015-pcm_file-fix-SEGFAULT-if-file-option-is-missing-whil.patch
+Patch16: 0016-pcm_file-fixed-memory-leak.patch
+Patch17: 0017-pcm_file-don-t-touch-infile-on-playback-and-output-f.patch
+Patch18: 0018-pcm_file-document-new-argument-to-snd_pcm_file_open.patch
+Patch19: 0019-dmix-Don-t-use-assert-and-abort.patch
# rest suse patches
Patch99: alsa-lib-doxygen-avoid-crash-for-11.3.diff
Url: http://www.alsa-project.org/
@@ -123,6 +133,16 @@ Architecture.
%patch7 -p1
%patch8 -p1
%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
%if %suse_version == 1130
%patch99 -p1
%endif
@@ -196,10 +216,12 @@ install -c -m 0644 %{SOURCE8} $RPM_BUILD_ROOT/etc/udev/rules.d
#
# modprobe config and the module install script for loading OSS-emulation
# and sequencer modules automatically
+%if %suse_version > 1220
mkdir -p $RPM_BUILD_ROOT/etc/modprobe.d
install -c -m 0644 %{S:40} $RPM_BUILD_ROOT/etc/modprobe.d
mkdir -p $RPM_BUILD_ROOT/sbin
install -c -m 0755 %{S:41} $RPM_BUILD_ROOT/sbin
+%endif
#
# install template to update rc.config and sysconfig files:
# (updating the actual files is done in the %post-script)
@@ -242,8 +264,10 @@ exit 0
%defattr(-, root, root)
%doc %{_docdir}/%{name}
/etc/init.d/*
+%if %suse_version > 1220
/etc/modprobe.d
/sbin/*
+%endif
%{_sbindir}/*
%{_bindir}/*
/usr/lib/all_notes_off.*