Accepting request 416688 from home:tiwai:branches:multimedia:libs
- Update to alsa-lib v1.1.2: * topology API updates * support of stacked async handlers * new UCM configs: rockchip-i2s, skylake-i2s, chtrt5645, * add cset-tlv ucm support * fix conversion of TLVs min_db and max_dB value in softvol * fix appl pointer in the error path of PCM plugin * PCM code cleanup * fix suspend/resume of PCM dmix, dsnoop and dshare plugins * fix doubly enumerated items via namehint * make PCM codes thread-safe * API documentation enhancements * element-set ctl API * Optimization by replacing alloca() usages - Drop obsoleted patches: 0001-pcm_plugin-fix-appl-pointer-not-correct-when-mmap_co.patch 0002-pcm-Clean-up-error-paths-in-snd_pcm_plugin_-helpers.patch 0003-pcm-Fallback-open-as-the-first-instance-for-dmix-co.patch 0004-pcm-softvol-fix-conversion-of-TLVs-min_db-and-max_dB.patch 0005-pcm-Fix-suspend-resume-regression-with-dmix-co.patch 0006-pcm-dmix-Fix-doubly-resume-of-slave-PCM.patch 0007-namehint-Don-t-enumerate-as-duplex-if-only-a-single-.patch 0008-pcm-Define-namehint-for-single-directional-PCM-types.patch 0009-conf-Add-thread-safe-global-tree-reference.patch 0010-pcm-Remove-resume-support-from-dmix-co.patch 0011-pcm-Fix-secondary-retry-in-dsnoop-and-dshare.patch 0012-pcm-dmix-resume-workaround-for-buggy-driver.patch 0013-pcm-dmix-Prepare-slave-when-it-s-in-SETUP-too.patch 0014-pcm-dmix-Return-error-when-slave-is-in-OPEN-or-DISCO.patch 0015-async-Handle-previously-installed-signal-handler.patch OBS-URL: https://build.opensuse.org/request/show/416688 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=200
This commit is contained in:
parent
d51e946615
commit
9d21ad3488
@ -1,135 +0,0 @@
|
||||
From 7c424edd116e76eee6218a1e9a6ff6c4daaf2a4d Mon Sep 17 00:00:00 2001
|
||||
From: Shengjiu Wang <shengjiu.wang@freescale.com>
|
||||
Date: Wed, 6 Apr 2016 19:02:12 +0800
|
||||
Subject: [PATCH] pcm_plugin: fix appl pointer not correct when mmap_commit()
|
||||
return error
|
||||
|
||||
When snd_pcm_mmap_commit() return error, the appl pointer is also updated.
|
||||
which cause the avail_update()'s result wrong.
|
||||
This patch move the snd_pcm_mmap_appl_forward() to the place when
|
||||
snd_pcm_mmap_commit() is successfully returned.
|
||||
|
||||
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_plugin.c | 48 ++++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 32 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
|
||||
index d007e8c8bd4a..940491dbc84b 100644
|
||||
--- a/src/pcm/pcm_plugin.c
|
||||
+++ b/src/pcm/pcm_plugin.c
|
||||
@@ -279,18 +279,22 @@ static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
|
||||
return -EPIPE;
|
||||
}
|
||||
snd_atomic_write_begin(&plugin->watom);
|
||||
- snd_pcm_mmap_appl_forward(pcm, frames);
|
||||
result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
|
||||
if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
|
||||
snd_pcm_sframes_t res;
|
||||
res = plugin->undo_write(pcm, slave_areas, slave_offset + result, slave_frames, slave_frames - result);
|
||||
- if (res < 0)
|
||||
+ if (res < 0) {
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
|
||||
+ }
|
||||
frames -= res;
|
||||
}
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
- if (result <= 0)
|
||||
+ if (result <= 0) {
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
|
||||
+ }
|
||||
+ snd_pcm_mmap_appl_forward(pcm, frames);
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
offset += frames;
|
||||
xfer += frames;
|
||||
size -= frames;
|
||||
@@ -325,19 +329,23 @@ static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
|
||||
return -EPIPE;
|
||||
}
|
||||
snd_atomic_write_begin(&plugin->watom);
|
||||
- snd_pcm_mmap_appl_forward(pcm, frames);
|
||||
result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
|
||||
if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
|
||||
snd_pcm_sframes_t res;
|
||||
|
||||
res = plugin->undo_read(slave, areas, offset, frames, slave_frames - result);
|
||||
- if (res < 0)
|
||||
+ if (res < 0) {
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
|
||||
+ }
|
||||
frames -= res;
|
||||
}
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
- if (result <= 0)
|
||||
+ if (result <= 0) {
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
|
||||
+ }
|
||||
+ snd_pcm_mmap_appl_forward(pcm, frames);
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
offset += frames;
|
||||
xfer += frames;
|
||||
size -= frames;
|
||||
@@ -423,19 +431,23 @@ snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
|
||||
frames = plugin->write(pcm, areas, appl_offset, frames,
|
||||
slave_areas, slave_offset, &slave_frames);
|
||||
snd_atomic_write_begin(&plugin->watom);
|
||||
- snd_pcm_mmap_appl_forward(pcm, frames);
|
||||
result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
|
||||
snd_pcm_sframes_t res;
|
||||
|
||||
res = plugin->undo_write(pcm, slave_areas, slave_offset + result, slave_frames, slave_frames - result);
|
||||
- if (res < 0)
|
||||
+ if (res < 0) {
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
return xfer > 0 ? xfer : res;
|
||||
+ }
|
||||
frames -= res;
|
||||
}
|
||||
- if (result <= 0)
|
||||
+ if (result <= 0) {
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
return xfer > 0 ? xfer : result;
|
||||
+ }
|
||||
+ snd_pcm_mmap_appl_forward(pcm, frames);
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
if (frames == cont)
|
||||
appl_offset = 0;
|
||||
else
|
||||
@@ -490,19 +502,23 @@ static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
|
||||
frames = (plugin->read)(pcm, areas, hw_offset, frames,
|
||||
slave_areas, slave_offset, &slave_frames);
|
||||
snd_atomic_write_begin(&plugin->watom);
|
||||
- snd_pcm_mmap_hw_forward(pcm, frames);
|
||||
result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
|
||||
snd_pcm_sframes_t res;
|
||||
|
||||
res = plugin->undo_read(slave, areas, hw_offset, frames, slave_frames - result);
|
||||
- if (res < 0)
|
||||
+ if (res < 0) {
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
|
||||
+ }
|
||||
frames -= res;
|
||||
}
|
||||
- if (result <= 0)
|
||||
+ if (result <= 0) {
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
|
||||
+ }
|
||||
+ snd_pcm_mmap_hw_forward(pcm, frames);
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
if (frames == cont)
|
||||
hw_offset = 0;
|
||||
else
|
||||
--
|
||||
2.8.2
|
||||
|
@ -1,213 +0,0 @@
|
||||
From 503a285ed60164d8c65c6ee9ba6f23631da753df Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Thu, 7 Apr 2016 16:29:41 +0200
|
||||
Subject: [PATCH] pcm: Clean up error paths in snd_pcm_plugin_*() helpers
|
||||
|
||||
Minor code refactoring to unify the error return paths.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_plugin.c | 67 +++++++++++++++++++++++++++++++++++-----------------
|
||||
1 file changed, 45 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
|
||||
index 940491dbc84b..8527783c3569 100644
|
||||
--- a/src/pcm/pcm_plugin.c
|
||||
+++ b/src/pcm/pcm_plugin.c
|
||||
@@ -276,7 +276,8 @@ static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
|
||||
if (CHECK_SANITY(slave_frames > snd_pcm_mmap_playback_avail(slave))) {
|
||||
SNDMSG("write overflow %ld > %ld", slave_frames,
|
||||
snd_pcm_mmap_playback_avail(slave));
|
||||
- return -EPIPE;
|
||||
+ err = -EPIPE;
|
||||
+ goto error;
|
||||
}
|
||||
snd_atomic_write_begin(&plugin->watom);
|
||||
result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
|
||||
@@ -284,14 +285,14 @@ static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
|
||||
snd_pcm_sframes_t res;
|
||||
res = plugin->undo_write(pcm, slave_areas, slave_offset + result, slave_frames, slave_frames - result);
|
||||
if (res < 0) {
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
|
||||
+ err = res;
|
||||
+ goto error_atomic;
|
||||
}
|
||||
frames -= res;
|
||||
}
|
||||
if (result <= 0) {
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
|
||||
+ err = result;
|
||||
+ goto error_atomic;
|
||||
}
|
||||
snd_pcm_mmap_appl_forward(pcm, frames);
|
||||
snd_atomic_write_end(&plugin->watom);
|
||||
@@ -300,6 +301,11 @@ static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
|
||||
size -= frames;
|
||||
}
|
||||
return (snd_pcm_sframes_t)xfer;
|
||||
+
|
||||
+ error_atomic:
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
+ error:
|
||||
+ return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
|
||||
@@ -311,6 +317,7 @@ static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
|
||||
snd_pcm_t *slave = plugin->gen.slave;
|
||||
snd_pcm_uframes_t xfer = 0;
|
||||
snd_pcm_sframes_t result;
|
||||
+ int err;
|
||||
|
||||
while (size > 0) {
|
||||
snd_pcm_uframes_t frames = size;
|
||||
@@ -326,7 +333,8 @@ static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
|
||||
if (CHECK_SANITY(slave_frames > snd_pcm_mmap_capture_avail(slave))) {
|
||||
SNDMSG("read overflow %ld > %ld", slave_frames,
|
||||
snd_pcm_mmap_playback_avail(slave));
|
||||
- return -EPIPE;
|
||||
+ err = -EPIPE;
|
||||
+ goto error;
|
||||
}
|
||||
snd_atomic_write_begin(&plugin->watom);
|
||||
result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
|
||||
@@ -335,14 +343,14 @@ static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
|
||||
|
||||
res = plugin->undo_read(slave, areas, offset, frames, slave_frames - result);
|
||||
if (res < 0) {
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
|
||||
+ err = res;
|
||||
+ goto error_atomic;
|
||||
}
|
||||
frames -= res;
|
||||
}
|
||||
if (result <= 0) {
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
|
||||
+ err = result;
|
||||
+ goto error_atomic;
|
||||
}
|
||||
snd_pcm_mmap_appl_forward(pcm, frames);
|
||||
snd_atomic_write_end(&plugin->watom);
|
||||
@@ -351,6 +359,11 @@ static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
|
||||
size -= frames;
|
||||
}
|
||||
return (snd_pcm_sframes_t)xfer;
|
||||
+
|
||||
+ error_atomic:
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
+ error:
|
||||
+ return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
|
||||
}
|
||||
|
||||
|
||||
@@ -401,6 +414,7 @@ snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
|
||||
snd_pcm_uframes_t appl_offset;
|
||||
snd_pcm_sframes_t slave_size;
|
||||
snd_pcm_sframes_t xfer;
|
||||
+ int err;
|
||||
|
||||
if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
|
||||
snd_atomic_write_begin(&plugin->watom);
|
||||
@@ -421,11 +435,10 @@ snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
|
||||
snd_pcm_uframes_t slave_offset;
|
||||
snd_pcm_uframes_t slave_frames = ULONG_MAX;
|
||||
snd_pcm_sframes_t result;
|
||||
- int err;
|
||||
|
||||
err = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
if (err < 0)
|
||||
- return xfer > 0 ? xfer : err;
|
||||
+ goto error;
|
||||
if (frames > cont)
|
||||
frames = cont;
|
||||
frames = plugin->write(pcm, areas, appl_offset, frames,
|
||||
@@ -437,14 +450,14 @@ snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
|
||||
|
||||
res = plugin->undo_write(pcm, slave_areas, slave_offset + result, slave_frames, slave_frames - result);
|
||||
if (res < 0) {
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
- return xfer > 0 ? xfer : res;
|
||||
+ err = res;
|
||||
+ goto error_atomic;
|
||||
}
|
||||
frames -= res;
|
||||
}
|
||||
if (result <= 0) {
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
- return xfer > 0 ? xfer : result;
|
||||
+ err = result;
|
||||
+ goto error_atomic;
|
||||
}
|
||||
snd_pcm_mmap_appl_forward(pcm, frames);
|
||||
snd_atomic_write_end(&plugin->watom);
|
||||
@@ -461,6 +474,11 @@ snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
|
||||
return -EPIPE;
|
||||
}
|
||||
return xfer;
|
||||
+
|
||||
+ error_atomic:
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
+ error:
|
||||
+ return xfer > 0 ? xfer : err;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
|
||||
@@ -468,6 +486,7 @@ static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
|
||||
snd_pcm_plugin_t *plugin = pcm->private_data;
|
||||
snd_pcm_t *slave = plugin->gen.slave;
|
||||
snd_pcm_sframes_t slave_size;
|
||||
+ int err;
|
||||
|
||||
slave_size = snd_pcm_avail_update(slave);
|
||||
if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
|
||||
@@ -492,11 +511,10 @@ static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
|
||||
snd_pcm_uframes_t slave_offset;
|
||||
snd_pcm_uframes_t slave_frames = ULONG_MAX;
|
||||
snd_pcm_sframes_t result;
|
||||
- int err;
|
||||
|
||||
err = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
if (err < 0)
|
||||
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
|
||||
+ goto error;
|
||||
if (frames > cont)
|
||||
frames = cont;
|
||||
frames = (plugin->read)(pcm, areas, hw_offset, frames,
|
||||
@@ -508,14 +526,14 @@ static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
|
||||
|
||||
res = plugin->undo_read(slave, areas, hw_offset, frames, slave_frames - result);
|
||||
if (res < 0) {
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
|
||||
+ err = res;
|
||||
+ goto error_atomic;
|
||||
}
|
||||
frames -= res;
|
||||
}
|
||||
if (result <= 0) {
|
||||
- snd_atomic_write_end(&plugin->watom);
|
||||
- return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
|
||||
+ err = result;
|
||||
+ goto error_atomic;
|
||||
}
|
||||
snd_pcm_mmap_hw_forward(pcm, frames);
|
||||
snd_atomic_write_end(&plugin->watom);
|
||||
@@ -528,6 +546,11 @@ static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
|
||||
xfer += frames;
|
||||
}
|
||||
return (snd_pcm_sframes_t)xfer;
|
||||
+
|
||||
+ error_atomic:
|
||||
+ snd_atomic_write_end(&plugin->watom);
|
||||
+ error:
|
||||
+ return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.8.2
|
||||
|
@ -1,106 +0,0 @@
|
||||
From fdba9e1bad8f769a6137e565471f0227f23a3132 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Thu, 14 Apr 2016 17:33:03 +0200
|
||||
Subject: [PATCH] pcm: Fallback open as the first instance for dmix & co
|
||||
|
||||
dmix and other PCM plugins tries to open a secondary stream with
|
||||
O_APPEND flag when the shmem was already attached by another.
|
||||
However, when another streams have been already closed after the
|
||||
shmem check, this open may return the error EBADFD, since the kernel
|
||||
accepts O_APPEND only for the secondary streams.
|
||||
|
||||
This patch adds a workaround for such a case. It just retries opening
|
||||
the stream as the first instance (i.e. without O_APPEND flag).
|
||||
This is basically safe behavior (the kernel takes care of races), even
|
||||
we may do this even unconditionally. But it's bad from the
|
||||
performance POV, so we do it only when really needed.
|
||||
|
||||
Reported-by: Lars Lindqvist <lars.lindqvist@yandex.ru>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_dmix.c | 8 ++++++++
|
||||
src/pcm/pcm_dshare.c | 8 ++++++++
|
||||
src/pcm/pcm_dsnoop.c | 8 ++++++++
|
||||
3 files changed, 24 insertions(+)
|
||||
|
||||
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
|
||||
index b26a5c790e7e..007d35664ce7 100644
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -1020,6 +1020,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
|
||||
dmix->max_periods = opts->max_periods;
|
||||
dmix->sync_ptr = snd_pcm_dmix_sync_ptr;
|
||||
|
||||
+ retry:
|
||||
if (first_instance) {
|
||||
/* recursion is already checked in
|
||||
snd_pcm_direct_get_slave_ipc_offset() */
|
||||
@@ -1076,6 +1077,13 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
|
||||
SND_PCM_APPEND,
|
||||
NULL);
|
||||
if (ret < 0) {
|
||||
+ /* all other streams have been closed;
|
||||
+ * retry as the first instance
|
||||
+ */
|
||||
+ if (ret == -EBADFD) {
|
||||
+ first_instance = 1;
|
||||
+ goto retry;
|
||||
+ }
|
||||
SNDERR("unable to open slave");
|
||||
goto _err;
|
||||
}
|
||||
diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
|
||||
index 58e47bbeac67..adb3587a2869 100644
|
||||
--- a/src/pcm/pcm_dshare.c
|
||||
+++ b/src/pcm/pcm_dshare.c
|
||||
@@ -690,6 +690,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||
break;
|
||||
}
|
||||
|
||||
+ retry:
|
||||
first_instance = ret = snd_pcm_direct_shm_create_or_connect(dshare);
|
||||
if (ret < 0) {
|
||||
SNDERR("unable to create IPC shm instance");
|
||||
@@ -758,6 +759,13 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||
SND_PCM_APPEND,
|
||||
NULL);
|
||||
if (ret < 0) {
|
||||
+ /* all other streams have been closed;
|
||||
+ * retry as the first instance
|
||||
+ */
|
||||
+ if (ret == -EBADFD) {
|
||||
+ first_instance = 1;
|
||||
+ goto retry;
|
||||
+ }
|
||||
SNDERR("unable to open slave");
|
||||
goto _err;
|
||||
}
|
||||
diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
|
||||
index 576c35b111cd..8ff0ba57cb14 100644
|
||||
--- a/src/pcm/pcm_dsnoop.c
|
||||
+++ b/src/pcm/pcm_dsnoop.c
|
||||
@@ -583,6 +583,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
||||
break;
|
||||
}
|
||||
|
||||
+ retry:
|
||||
first_instance = ret = snd_pcm_direct_shm_create_or_connect(dsnoop);
|
||||
if (ret < 0) {
|
||||
SNDERR("unable to create IPC shm instance");
|
||||
@@ -651,6 +652,13 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
||||
SND_PCM_APPEND,
|
||||
NULL);
|
||||
if (ret < 0) {
|
||||
+ /* all other streams have been closed;
|
||||
+ * retry as the first instance
|
||||
+ */
|
||||
+ if (ret == -EBADFD) {
|
||||
+ first_instance = 1;
|
||||
+ goto retry;
|
||||
+ }
|
||||
SNDERR("unable to open slave");
|
||||
goto _err;
|
||||
}
|
||||
--
|
||||
2.8.2
|
||||
|
@ -1,89 +0,0 @@
|
||||
From 85bf9915989e0a338632739684c75192c1753239 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?J=C3=B6rg=20Krause?= <joerg.krause@embedded.rocks>
|
||||
Date: Sun, 8 May 2016 20:48:42 +0200
|
||||
Subject: [PATCH] pcm: softvol: fix conversion of TLVs min_db and max_dB value
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Both, min_dB and max_dB, are floating type whereas the TLV is (always)
|
||||
unsigned.
|
||||
|
||||
The problem with the conversion of a negative floating-point number into an
|
||||
unsigned integer is, that the behavior is undefined. This may, depending on
|
||||
the platform, result in a wrong TLV, i.e. for the default values of min_dB
|
||||
(-51dB) and max_dB (0dB), alsactl generates the following state on an ARM
|
||||
cpu build with GCC:
|
||||
|
||||
control.1 {
|
||||
iface MIXER
|
||||
name Master
|
||||
value.0 255
|
||||
value.1 255
|
||||
comment {
|
||||
access 'read write user'
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 255'
|
||||
tlv '00000001000000080000000000000014'
|
||||
dbmin 0
|
||||
dbmax 5100
|
||||
dbvalue.0 5100
|
||||
dbvalue.1 5100
|
||||
}
|
||||
}
|
||||
|
||||
With the fix applied, alsactl stores the correct TLV:
|
||||
|
||||
control.1 {
|
||||
iface MIXER
|
||||
name Master
|
||||
value.0 255
|
||||
value.1 255
|
||||
comment {
|
||||
access 'read write user'
|
||||
type INTEGER
|
||||
count 2
|
||||
range '0 - 255'
|
||||
tlv '0000000100000008ffffec1400000014'
|
||||
dbmin -5100
|
||||
dbmax 0
|
||||
dbvalue.0 0
|
||||
dbvalue.1 0
|
||||
}
|
||||
}
|
||||
|
||||
Also tested for different combinations of min_dB and max_dB other than the
|
||||
default values.
|
||||
|
||||
Replaces:
|
||||
http://mailman.alsa-project.org/pipermail/alsa-devel/2016-May/107733.html
|
||||
|
||||
Fixes:
|
||||
http://mailman.alsa-project.org/pipermail/alsa-devel/2016-May/107628.html
|
||||
|
||||
Cc: Clemens Ladisch <clemens@ladisch.de>
|
||||
Signed-off-by: Jörg Krause <joerg.krause@embedded.rocks>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_softvol.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c
|
||||
index 802aa4b7cb68..5492db8cf9f1 100644
|
||||
--- a/src/pcm/pcm_softvol.c
|
||||
+++ b/src/pcm/pcm_softvol.c
|
||||
@@ -658,8 +658,8 @@ static int add_tlv_info(snd_pcm_softvol_t *svol, snd_ctl_elem_info_t *cinfo)
|
||||
unsigned int tlv[4];
|
||||
tlv[0] = SND_CTL_TLVT_DB_SCALE;
|
||||
tlv[1] = 2 * sizeof(int);
|
||||
- tlv[2] = svol->min_dB * 100;
|
||||
- tlv[3] = (svol->max_dB - svol->min_dB) * 100 / svol->max_val;
|
||||
+ tlv[2] = (int)(svol->min_dB * 100);
|
||||
+ tlv[3] = (int)((svol->max_dB - svol->min_dB) * 100 / svol->max_val);
|
||||
return snd_ctl_elem_tlv_write(svol->ctl, &cinfo->id, tlv);
|
||||
}
|
||||
|
||||
--
|
||||
2.8.2
|
||||
|
@ -1,40 +0,0 @@
|
||||
From c14b0a08f0bf58e4f62307c68f8ff0137b4dec19 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Wed, 11 May 2016 09:06:47 +0200
|
||||
Subject: [PATCH] pcm: Fix suspend/resume regression with dmix & co
|
||||
|
||||
The recent fix commit [8985742d91db: pcm: dmix: Handle slave PCM xrun
|
||||
and unexpected states properly] caused a regression in dmix and other
|
||||
plugins regarding suspend/resume. For example, aplay endlessly prints
|
||||
"Suspended. Trying resume. Done." message if suspend and resume are
|
||||
performed in the middle of playback.
|
||||
|
||||
The reason is that the commit above changed the shadow PCM state
|
||||
(dmix->state) to SUSPENDED when the slave PCM is in suspend, while it
|
||||
doesn't restore the shadow state upon resume. Thus it appears as if
|
||||
it's always suspended even after the resume is invoked.
|
||||
|
||||
The fix is just to add the proper update of the shadow state in
|
||||
snd_pcm_direct_resume().
|
||||
|
||||
Reported-by: Shengjiu Wang <shengjiu.wang@freescale.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
|
||||
index 14de734d98eb..e28738b0de96 100644
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -848,6 +848,7 @@ int snd_pcm_direct_resume(snd_pcm_t *pcm)
|
||||
snd_pcm_start(dmix->spcm);
|
||||
err = 0;
|
||||
}
|
||||
+ dmix->state = snd_pcm_state(dmix->spcm);
|
||||
snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||
return err;
|
||||
}
|
||||
--
|
||||
2.8.2
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 5610b356b5f110f7f8e586f56e5b74e0f0c2db38 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Wed, 11 May 2016 13:06:25 +0200
|
||||
Subject: [PATCH] pcm: dmix: Fix doubly resume of slave PCM
|
||||
|
||||
The dmix plugin and co may trigger the resume for each instance in
|
||||
snd_pcm_direct_resume(). It means that the slave PCM gets resumed or
|
||||
re-prepared/started by each opened dmix stream, and this may end up
|
||||
with the doubly triggers even though the slave PCM has been already
|
||||
resumed by another dmix stream.
|
||||
|
||||
For avoiding this conflicts, check the slave PCM state and resume only
|
||||
when it's still in the suspended state. Meanwhile we keep the shadow
|
||||
state updated no matter whether the slave was triggered or not.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
|
||||
index e28738b0de96..ac082f1a73b2 100644
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -841,6 +841,12 @@ int snd_pcm_direct_resume(snd_pcm_t *pcm)
|
||||
int err;
|
||||
|
||||
snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||
+ /* resume only when the slave PCM is still in suspended state */
|
||||
+ if (snd_pcm_state(dmix->spcm) != SND_PCM_STATE_SUSPENDED) {
|
||||
+ err = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
err = snd_pcm_resume(dmix->spcm);
|
||||
if (err == -ENOSYS) {
|
||||
/* FIXME: error handling? */
|
||||
@@ -848,6 +854,7 @@ int snd_pcm_direct_resume(snd_pcm_t *pcm)
|
||||
snd_pcm_start(dmix->spcm);
|
||||
err = 0;
|
||||
}
|
||||
+ out:
|
||||
dmix->state = snd_pcm_state(dmix->spcm);
|
||||
snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||
return err;
|
||||
--
|
||||
2.8.2
|
||||
|
@ -1,62 +0,0 @@
|
||||
From 8cdbdae73109c901aec4984f6ba65e5b25722f13 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Thu, 12 May 2016 16:30:44 +0200
|
||||
Subject: [PATCH 07/15] namehint: Don't enumerate as duplex if only a single
|
||||
direction is defined
|
||||
|
||||
When a hint description has only either device_input or device_output,
|
||||
we shouldn't handle it as a full duplex but rather a single
|
||||
direction. In that way, we can avoid to list up a playback stream
|
||||
like dmix or surround51 as a capture stream in the namehint.
|
||||
|
||||
Reported-by: Trent Reed <treed0803@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/control/namehint.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/control/namehint.c b/src/control/namehint.c
|
||||
index 856957c76d74..ad8dda37a637 100644
|
||||
--- a/src/control/namehint.c
|
||||
+++ b/src/control/namehint.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "local.h"
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
+#define DEV_SKIP 9999 /* some non-existing device number */
|
||||
struct hint_list {
|
||||
char **list;
|
||||
unsigned int count;
|
||||
@@ -90,7 +91,7 @@ static int get_dev_name1(struct hint_list *list, char **res, int device,
|
||||
int stream)
|
||||
{
|
||||
*res = NULL;
|
||||
- if (device < 0)
|
||||
+ if (device < 0 || device == DEV_SKIP)
|
||||
return 0;
|
||||
switch (list->iface) {
|
||||
#ifdef BUILD_HWDEP
|
||||
@@ -317,7 +318,9 @@ static int try_config(snd_config_t *config,
|
||||
err = -EINVAL;
|
||||
goto __cleanup;
|
||||
}
|
||||
- list->device_output = -1;
|
||||
+ /* skip the counterpart if only a single direction is defined */
|
||||
+ if (list->device_output < 0)
|
||||
+ list->device_output = DEV_SKIP;
|
||||
}
|
||||
if (snd_config_search(cfg, "device_output", &n) >= 0) {
|
||||
if (snd_config_get_integer(n, &list->device_output) < 0) {
|
||||
@@ -325,6 +328,9 @@ static int try_config(snd_config_t *config,
|
||||
err = -EINVAL;
|
||||
goto __cleanup;
|
||||
}
|
||||
+ /* skip the counterpart if only a single direction is defined */
|
||||
+ if (list->device_input < 0)
|
||||
+ list->device_input = DEV_SKIP;
|
||||
}
|
||||
} else if (level == 1 && !list->show_all)
|
||||
goto __skip_add;
|
||||
--
|
||||
2.8.3
|
||||
|
@ -1,120 +0,0 @@
|
||||
From 5fb3fe17249c3fffb8b8e15108ff72f27ba5e81c Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Thu, 12 May 2016 16:33:19 +0200
|
||||
Subject: [PATCH 08/15] pcm: Define namehint for single directional PCM types
|
||||
|
||||
The PCM namehint for some PCM types like dmix, dsnoop and surround51
|
||||
should be defined as single directional.
|
||||
|
||||
Reported-by: Trent Reed <treed0803@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/conf/pcm/dmix.conf | 2 +-
|
||||
src/conf/pcm/dsnoop.conf | 2 +-
|
||||
src/conf/pcm/surround21.conf | 2 +-
|
||||
src/conf/pcm/surround40.conf | 2 +-
|
||||
src/conf/pcm/surround41.conf | 2 +-
|
||||
src/conf/pcm/surround50.conf | 2 +-
|
||||
src/conf/pcm/surround51.conf | 2 +-
|
||||
src/conf/pcm/surround71.conf | 2 +-
|
||||
8 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/conf/pcm/dmix.conf b/src/conf/pcm/dmix.conf
|
||||
index e62cb295278c..7d0aa0158c42 100644
|
||||
--- a/src/conf/pcm/dmix.conf
|
||||
+++ b/src/conf/pcm/dmix.conf
|
||||
@@ -110,6 +110,6 @@ pcm.!dmix {
|
||||
name defaults.namehint.extended
|
||||
}
|
||||
description "Direct sample mixing device"
|
||||
- device $DEV
|
||||
+ device_output $DEV
|
||||
}
|
||||
}
|
||||
diff --git a/src/conf/pcm/dsnoop.conf b/src/conf/pcm/dsnoop.conf
|
||||
index 49cfca98c262..abbd44f7fd79 100644
|
||||
--- a/src/conf/pcm/dsnoop.conf
|
||||
+++ b/src/conf/pcm/dsnoop.conf
|
||||
@@ -110,6 +110,6 @@ pcm.!dsnoop {
|
||||
name defaults.namehint.extended
|
||||
}
|
||||
description "Direct sample snooping device"
|
||||
- device $DEV
|
||||
+ device_input $DEV
|
||||
}
|
||||
}
|
||||
diff --git a/src/conf/pcm/surround21.conf b/src/conf/pcm/surround21.conf
|
||||
index 7f4676b3f714..1cf1b7af8dc6 100644
|
||||
--- a/src/conf/pcm/surround21.conf
|
||||
+++ b/src/conf/pcm/surround21.conf
|
||||
@@ -56,6 +56,6 @@ pcm.!surround21 {
|
||||
ttable.2.LFE 1
|
||||
hint {
|
||||
description "2.1 Surround output to Front and Subwoofer speakers"
|
||||
- device $DEV
|
||||
+ device_output $DEV
|
||||
}
|
||||
}
|
||||
diff --git a/src/conf/pcm/surround40.conf b/src/conf/pcm/surround40.conf
|
||||
index 361ccaa1e329..9788ad4884fd 100644
|
||||
--- a/src/conf/pcm/surround40.conf
|
||||
+++ b/src/conf/pcm/surround40.conf
|
||||
@@ -54,6 +54,6 @@ pcm.!surround40 {
|
||||
}
|
||||
hint {
|
||||
description "4.0 Surround output to Front and Rear speakers"
|
||||
- device $DEV
|
||||
+ device_output $DEV
|
||||
}
|
||||
}
|
||||
diff --git a/src/conf/pcm/surround41.conf b/src/conf/pcm/surround41.conf
|
||||
index 2f823815821a..7b4ef3beb43a 100644
|
||||
--- a/src/conf/pcm/surround41.conf
|
||||
+++ b/src/conf/pcm/surround41.conf
|
||||
@@ -60,6 +60,6 @@ pcm.!surround41 {
|
||||
ttable.4.LFE 1
|
||||
hint {
|
||||
description "4.1 Surround output to Front, Rear and Subwoofer speakers"
|
||||
- device $DEV
|
||||
+ device_output $DEV
|
||||
}
|
||||
}
|
||||
diff --git a/src/conf/pcm/surround50.conf b/src/conf/pcm/surround50.conf
|
||||
index dc95c179da68..7d9a9e798fd8 100644
|
||||
--- a/src/conf/pcm/surround50.conf
|
||||
+++ b/src/conf/pcm/surround50.conf
|
||||
@@ -60,6 +60,6 @@ pcm.!surround50 {
|
||||
ttable.4.FC 1
|
||||
hint {
|
||||
description "5.0 Surround output to Front, Center and Rear speakers"
|
||||
- device $DEV
|
||||
+ device_output $DEV
|
||||
}
|
||||
}
|
||||
diff --git a/src/conf/pcm/surround51.conf b/src/conf/pcm/surround51.conf
|
||||
index 3a7543f9fb8a..e67f007ef305 100644
|
||||
--- a/src/conf/pcm/surround51.conf
|
||||
+++ b/src/conf/pcm/surround51.conf
|
||||
@@ -56,6 +56,6 @@ pcm.!surround51 {
|
||||
}
|
||||
hint {
|
||||
description "5.1 Surround output to Front, Center, Rear and Subwoofer speakers"
|
||||
- device $DEV
|
||||
+ device_output $DEV
|
||||
}
|
||||
}
|
||||
diff --git a/src/conf/pcm/surround71.conf b/src/conf/pcm/surround71.conf
|
||||
index 076a97d73716..a26c3f36c437 100644
|
||||
--- a/src/conf/pcm/surround71.conf
|
||||
+++ b/src/conf/pcm/surround71.conf
|
||||
@@ -58,6 +58,6 @@ pcm.!surround71 {
|
||||
}
|
||||
hint {
|
||||
description "7.1 Surround output to Front, Center, Side, Rear and Woofer speakers"
|
||||
- device $DEV
|
||||
+ device_output $DEV
|
||||
}
|
||||
}
|
||||
--
|
||||
2.8.3
|
||||
|
@ -1,339 +0,0 @@
|
||||
From c9a0d7d601e8ab069f8745968c03c8470b24d20d Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Tue, 17 May 2016 15:39:07 +0200
|
||||
Subject: [PATCH 09/15] conf: Add thread-safe global tree reference
|
||||
|
||||
Most of open functions in alsa-lib have the call pattern:
|
||||
snd_config_update();
|
||||
return snd_xxx_open(x, snd_config, ...);
|
||||
|
||||
This means that the toplevel config gets updated, and passed to a
|
||||
local open function. Although snd_config_update() itself has a
|
||||
pthread mutex to be thread safe, the whole procedure above isn't
|
||||
thread safe. Namely, the global snd_config tree may be deleted and
|
||||
recreated at any time while the open function is being processed.
|
||||
This may lead to a data corruption and crash of the program.
|
||||
|
||||
For avoiding the corruption, this patch introduces a refcount to
|
||||
config tree object. A few new helper functions are introduced as
|
||||
well:
|
||||
- snd_config_update_ref() does update and take the refcount of the
|
||||
toplevel tree. The obtained config tree has to be freed via
|
||||
snd_config_unref() below.
|
||||
- snd_config_ref() and snd_config_unref() manage the refcount of the
|
||||
config object. The latter eventually deletes the object when all
|
||||
references are gone.
|
||||
|
||||
Along with these additions, the caller of snd_config_update() and
|
||||
snd_config global tree in alsa-lib are replaced with the new helpers.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
include/conf.h | 4 +++
|
||||
src/conf.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
src/control/control.c | 8 +++--
|
||||
src/hwdep/hwdep.c | 8 +++--
|
||||
src/pcm/pcm.c | 8 +++--
|
||||
src/rawmidi/rawmidi.c | 8 +++--
|
||||
src/seq/seq.c | 8 +++--
|
||||
src/timer/timer.c | 8 +++--
|
||||
src/timer/timer_query.c | 8 +++--
|
||||
9 files changed, 125 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/include/conf.h b/include/conf.h
|
||||
index 087c05dc6bcf..5d293d583fbb 100644
|
||||
--- a/include/conf.h
|
||||
+++ b/include/conf.h
|
||||
@@ -94,6 +94,10 @@ int snd_config_update_r(snd_config_t **top, snd_config_update_t **update, const
|
||||
int snd_config_update_free(snd_config_update_t *update);
|
||||
int snd_config_update_free_global(void);
|
||||
|
||||
+int snd_config_update_ref(snd_config_t **top);
|
||||
+void snd_config_ref(snd_config_t *top);
|
||||
+void snd_config_unref(snd_config_t *top);
|
||||
+
|
||||
int snd_config_search(snd_config_t *config, const char *key,
|
||||
snd_config_t **result);
|
||||
int snd_config_searchv(snd_config_t *config,
|
||||
diff --git a/src/conf.c b/src/conf.c
|
||||
index f8b7a6686529..a516611427ac 100644
|
||||
--- a/src/conf.c
|
||||
+++ b/src/conf.c
|
||||
@@ -434,6 +434,7 @@ static pthread_once_t snd_config_update_mutex_once = PTHREAD_ONCE_INIT;
|
||||
struct _snd_config {
|
||||
char *id;
|
||||
snd_config_type_t type;
|
||||
+ int refcount; /* default = 0 */
|
||||
union {
|
||||
long integer;
|
||||
long long integer64;
|
||||
@@ -1825,6 +1826,10 @@ int snd_config_remove(snd_config_t *config)
|
||||
* If the node is a compound node, its descendants (the whole subtree)
|
||||
* are deleted recursively.
|
||||
*
|
||||
+ * The function is supposed to be called only for locally copied config
|
||||
+ * trees. For the global tree, take the reference via #snd_config_update_ref
|
||||
+ * and free it via #snd_config_unref.
|
||||
+ *
|
||||
* \par Conforming to:
|
||||
* LSB 3.2
|
||||
*
|
||||
@@ -1833,6 +1838,10 @@ int snd_config_remove(snd_config_t *config)
|
||||
int snd_config_delete(snd_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
+ if (config->refcount > 0) {
|
||||
+ config->refcount--;
|
||||
+ return 0;
|
||||
+ }
|
||||
switch (config->type) {
|
||||
case SND_CONFIG_TYPE_COMPOUND:
|
||||
{
|
||||
@@ -3833,6 +3842,8 @@ int snd_config_update_r(snd_config_t **_top, snd_config_update_t **_update, cons
|
||||
* \warning Whenever #snd_config is updated, all string pointers and
|
||||
* configuration node handles previously obtained from it may become
|
||||
* invalid.
|
||||
+ * For safer operations, use #snd_config_update_ref and release the config
|
||||
+ * via #snd_config_unref.
|
||||
*
|
||||
* \par Errors:
|
||||
* Any errors encountered when parsing the input or returned by hooks or
|
||||
@@ -3851,6 +3862,74 @@ int snd_config_update(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * \brief Updates #snd_config and takes its reference.
|
||||
+ * \return 0 if #snd_config was up to date, 1 if #snd_config was
|
||||
+ * updated, otherwise a negative error code.
|
||||
+ *
|
||||
+ * Unlike #snd_config_update, this function increases a reference counter
|
||||
+ * so that the obtained tree won't be deleted until unreferenced by
|
||||
+ * #snd_config_unref.
|
||||
+ *
|
||||
+ * This function is supposed to be thread-safe.
|
||||
+ */
|
||||
+int snd_config_update_ref(snd_config_t **top)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ if (top)
|
||||
+ *top = NULL;
|
||||
+ snd_config_lock();
|
||||
+ err = snd_config_update_r(&snd_config, &snd_config_global_update, NULL);
|
||||
+ if (err >= 0) {
|
||||
+ if (snd_config) {
|
||||
+ if (top) {
|
||||
+ snd_config->refcount++;
|
||||
+ *top = snd_config;
|
||||
+ }
|
||||
+ } else {
|
||||
+ err = -ENODEV;
|
||||
+ }
|
||||
+ }
|
||||
+ snd_config_unlock();
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * \brief Take the reference of the config tree.
|
||||
+ *
|
||||
+ * Increases a reference counter of the given config tree.
|
||||
+ *
|
||||
+ * This function is supposed to be thread-safe.
|
||||
+ */
|
||||
+void snd_config_ref(snd_config_t *cfg)
|
||||
+{
|
||||
+ snd_config_lock();
|
||||
+ if (cfg)
|
||||
+ cfg->refcount++;
|
||||
+ snd_config_unlock();
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * \brief Unreference the config tree.
|
||||
+ *
|
||||
+ * Decreases a reference counter of the given config tree, and eventually
|
||||
+ * deletes the tree if all references are gone. This is the counterpart of
|
||||
+ * #snd_config_unref.
|
||||
+ *
|
||||
+ * Also, the config taken via #snd_config_update_ref must be unreferenced
|
||||
+ * by this function, too.
|
||||
+ *
|
||||
+ * This function is supposed to be thread-safe.
|
||||
+ */
|
||||
+void snd_config_unref(snd_config_t *cfg)
|
||||
+{
|
||||
+ snd_config_lock();
|
||||
+ if (cfg)
|
||||
+ snd_config_delete(cfg);
|
||||
+ snd_config_unlock();
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* \brief Frees a private update structure.
|
||||
* \param[in] update The private update structure to free.
|
||||
diff --git a/src/control/control.c b/src/control/control.c
|
||||
index 8a5d530f2674..ae7884313c63 100644
|
||||
--- a/src/control/control.c
|
||||
+++ b/src/control/control.c
|
||||
@@ -968,12 +968,16 @@ static int snd_ctl_open_noupdate(snd_ctl_t **ctlp, snd_config_t *root, const cha
|
||||
*/
|
||||
int snd_ctl_open(snd_ctl_t **ctlp, const char *name, int mode)
|
||||
{
|
||||
+ snd_config_t *top;
|
||||
int err;
|
||||
+
|
||||
assert(ctlp && name);
|
||||
- err = snd_config_update();
|
||||
+ err = snd_config_update_ref(&top);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- return snd_ctl_open_noupdate(ctlp, snd_config, name, mode);
|
||||
+ err = snd_ctl_open_noupdate(ctlp, top, name, mode);
|
||||
+ snd_config_unref(top);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/src/hwdep/hwdep.c b/src/hwdep/hwdep.c
|
||||
index 5dc791c99189..bac634bae14a 100644
|
||||
--- a/src/hwdep/hwdep.c
|
||||
+++ b/src/hwdep/hwdep.c
|
||||
@@ -168,12 +168,16 @@ static int snd_hwdep_open_noupdate(snd_hwdep_t **hwdep, snd_config_t *root, cons
|
||||
*/
|
||||
int snd_hwdep_open(snd_hwdep_t **hwdep, const char *name, int mode)
|
||||
{
|
||||
+ snd_config_t *top;
|
||||
int err;
|
||||
+
|
||||
assert(hwdep && name);
|
||||
- err = snd_config_update();
|
||||
+ err = snd_config_update_ref(&top);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- return snd_hwdep_open_noupdate(hwdep, snd_config, name, mode);
|
||||
+ err = snd_hwdep_open_noupdate(hwdep, top, name, mode);
|
||||
+ snd_config_unref(top);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
|
||||
index 203e7a52491b..0d0d093deb49 100644
|
||||
--- a/src/pcm/pcm.c
|
||||
+++ b/src/pcm/pcm.c
|
||||
@@ -2288,12 +2288,16 @@ static int snd_pcm_open_noupdate(snd_pcm_t **pcmp, snd_config_t *root,
|
||||
int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
|
||||
snd_pcm_stream_t stream, int mode)
|
||||
{
|
||||
+ snd_config_t *top;
|
||||
int err;
|
||||
+
|
||||
assert(pcmp && name);
|
||||
- err = snd_config_update();
|
||||
+ err = snd_config_update_ref(&top);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- return snd_pcm_open_noupdate(pcmp, snd_config, name, stream, mode, 0);
|
||||
+ err = snd_pcm_open_noupdate(pcmp, top, name, stream, mode, 0);
|
||||
+ snd_config_unref(top);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/src/rawmidi/rawmidi.c b/src/rawmidi/rawmidi.c
|
||||
index 0c89b8b984b9..4701b4375359 100644
|
||||
--- a/src/rawmidi/rawmidi.c
|
||||
+++ b/src/rawmidi/rawmidi.c
|
||||
@@ -305,12 +305,16 @@ static int snd_rawmidi_open_noupdate(snd_rawmidi_t **inputp, snd_rawmidi_t **out
|
||||
int snd_rawmidi_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
|
||||
const char *name, int mode)
|
||||
{
|
||||
+ snd_config_t *top;
|
||||
int err;
|
||||
+
|
||||
assert((inputp || outputp) && name);
|
||||
- err = snd_config_update();
|
||||
+ err = snd_config_update_ref(&top);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- return snd_rawmidi_open_noupdate(inputp, outputp, snd_config, name, mode);
|
||||
+ err = snd_rawmidi_open_noupdate(inputp, outputp, top, name, mode);
|
||||
+ snd_config_unref(top);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/src/seq/seq.c b/src/seq/seq.c
|
||||
index 4405e68a7fe9..92798308a3b0 100644
|
||||
--- a/src/seq/seq.c
|
||||
+++ b/src/seq/seq.c
|
||||
@@ -974,12 +974,16 @@ static int snd_seq_open_noupdate(snd_seq_t **seqp, snd_config_t *root,
|
||||
int snd_seq_open(snd_seq_t **seqp, const char *name,
|
||||
int streams, int mode)
|
||||
{
|
||||
+ snd_config_t *top;
|
||||
int err;
|
||||
+
|
||||
assert(seqp && name);
|
||||
- err = snd_config_update();
|
||||
+ err = snd_config_update_ref(&top);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- return snd_seq_open_noupdate(seqp, snd_config, name, streams, mode, 0);
|
||||
+ err = snd_seq_open_noupdate(seqp, top, name, streams, mode, 0);
|
||||
+ snd_config_unref(top);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/src/timer/timer.c b/src/timer/timer.c
|
||||
index a25e4f797ce4..b25347117cba 100644
|
||||
--- a/src/timer/timer.c
|
||||
+++ b/src/timer/timer.c
|
||||
@@ -201,12 +201,16 @@ static int snd_timer_open_noupdate(snd_timer_t **timer, snd_config_t *root, cons
|
||||
*/
|
||||
int snd_timer_open(snd_timer_t **timer, const char *name, int mode)
|
||||
{
|
||||
+ snd_config_t *top;
|
||||
int err;
|
||||
+
|
||||
assert(timer && name);
|
||||
- err = snd_config_update();
|
||||
+ err = snd_config_update_ref(&top);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- return snd_timer_open_noupdate(timer, snd_config, name, mode);
|
||||
+ err = snd_timer_open_noupdate(timer, top, name, mode);
|
||||
+ snd_config_unref(top);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/src/timer/timer_query.c b/src/timer/timer_query.c
|
||||
index 93d2455d07fc..2072ceaea349 100644
|
||||
--- a/src/timer/timer_query.c
|
||||
+++ b/src/timer/timer_query.c
|
||||
@@ -159,12 +159,16 @@ static int snd_timer_query_open_noupdate(snd_timer_query_t **timer, snd_config_t
|
||||
*/
|
||||
int snd_timer_query_open(snd_timer_query_t **timer, const char *name, int mode)
|
||||
{
|
||||
+ snd_config_t *top;
|
||||
int err;
|
||||
+
|
||||
assert(timer && name);
|
||||
- err = snd_config_update();
|
||||
+ err = snd_config_update_ref(&top);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- return snd_timer_query_open_noupdate(timer, snd_config, name, mode);
|
||||
+ err = snd_timer_query_open_noupdate(timer, top, name, mode);
|
||||
+ snd_config_unref(top);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.8.3
|
||||
|
@ -1,70 +0,0 @@
|
||||
From d942498bfbd315c4c4559ccd573685e09aa03383 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Wed, 18 May 2016 10:38:27 +0200
|
||||
Subject: [PATCH 10/15] pcm: Remove resume support from dmix & co
|
||||
|
||||
PCM dmix and other plugins inherit the resume behavior from the slave
|
||||
PCM. However, the resume on dmix can't work reliably even if the
|
||||
slave PCM may do resume. The running state of each dmix stream is
|
||||
individual and may be PREPARED or RUN_PENDING while the slave PCM is
|
||||
already in RUNNING. And, when the slave PCM is resumed, the whole
|
||||
samples that have been already mapped are also played back, even if
|
||||
the corresponding dmix stream is still in SUSPENDED. Such
|
||||
inconsistencies can't be avoided as long as we manage each stream
|
||||
individually.
|
||||
|
||||
That said, dmix & co can't provide the proper resume support "by
|
||||
design". For aligning with it, we should drop the whole resume code
|
||||
and clear the PCM SND_PCM_INFO_RESUME flag.
|
||||
|
||||
Reported-by: Shengjiu Wang <shengjiu.wang@nxp.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 24 ++----------------------
|
||||
1 file changed, 2 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
|
||||
index ac082f1a73b2..53c49929cb1f 100644
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -837,27 +837,7 @@ int snd_pcm_direct_prepare(snd_pcm_t *pcm)
|
||||
|
||||
int snd_pcm_direct_resume(snd_pcm_t *pcm)
|
||||
{
|
||||
- snd_pcm_direct_t *dmix = pcm->private_data;
|
||||
- int err;
|
||||
-
|
||||
- snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||
- /* resume only when the slave PCM is still in suspended state */
|
||||
- if (snd_pcm_state(dmix->spcm) != SND_PCM_STATE_SUSPENDED) {
|
||||
- err = 0;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- err = snd_pcm_resume(dmix->spcm);
|
||||
- if (err == -ENOSYS) {
|
||||
- /* FIXME: error handling? */
|
||||
- snd_pcm_prepare(dmix->spcm);
|
||||
- snd_pcm_start(dmix->spcm);
|
||||
- err = 0;
|
||||
- }
|
||||
- out:
|
||||
- dmix->state = snd_pcm_state(dmix->spcm);
|
||||
- snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||
- return err;
|
||||
+ return -ENOSYS;
|
||||
}
|
||||
|
||||
#define COPY_SLAVE(field) (dmix->shmptr->s.field = spcm->field)
|
||||
@@ -865,7 +845,7 @@ int snd_pcm_direct_resume(snd_pcm_t *pcm)
|
||||
/* copy the slave setting */
|
||||
static void save_slave_setting(snd_pcm_direct_t *dmix, snd_pcm_t *spcm)
|
||||
{
|
||||
- spcm->info &= ~SND_PCM_INFO_PAUSE;
|
||||
+ spcm->info &= ~(SND_PCM_INFO_PAUSE | SND_PCM_INFO_RESUME);
|
||||
|
||||
COPY_SLAVE(access);
|
||||
COPY_SLAVE(format);
|
||||
--
|
||||
2.8.3
|
||||
|
@ -1,67 +0,0 @@
|
||||
From 2fa36eb03c000560128f7abce701536546b4a618 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Sat, 28 May 2016 10:37:26 +0200
|
||||
Subject: [PATCH 11/15] pcm: Fix secondary retry in dsnoop and dshare
|
||||
|
||||
The commit [fdba9e1bad8f: pcm: Fallback open as the first instance for
|
||||
dmix & co] introduced a mechanism to retry the open of slave PCM for
|
||||
the secondary streams, but this also introduced a regression in dsnoop
|
||||
and dshare plugins: since the retry goto-tag was placed at a wrong
|
||||
position, it retries to re-fetch the shm unnecessarily and eventually
|
||||
leads to the fatal error.
|
||||
|
||||
The bug can be easily reproduced by starting arecord and killing it
|
||||
via SIGKILL, then starting arecord again. The second arecord fails.
|
||||
|
||||
The fix is obviously to move the wrong retry goto-tags to the right
|
||||
positions.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_dshare.c | 2 +-
|
||||
src/pcm/pcm_dsnoop.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
|
||||
index adb3587a2869..05854dedf259 100644
|
||||
--- a/src/pcm/pcm_dshare.c
|
||||
+++ b/src/pcm/pcm_dshare.c
|
||||
@@ -690,7 +690,6 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||
break;
|
||||
}
|
||||
|
||||
- retry:
|
||||
first_instance = ret = snd_pcm_direct_shm_create_or_connect(dshare);
|
||||
if (ret < 0) {
|
||||
SNDERR("unable to create IPC shm instance");
|
||||
@@ -705,6 +704,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||
dshare->max_periods = opts->max_periods;
|
||||
dshare->sync_ptr = snd_pcm_dshare_sync_ptr;
|
||||
|
||||
+ retry:
|
||||
if (first_instance) {
|
||||
/* recursion is already checked in
|
||||
snd_pcm_direct_get_slave_ipc_offset() */
|
||||
diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
|
||||
index 8ff0ba57cb14..2d45171dda01 100644
|
||||
--- a/src/pcm/pcm_dsnoop.c
|
||||
+++ b/src/pcm/pcm_dsnoop.c
|
||||
@@ -583,7 +583,6 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
||||
break;
|
||||
}
|
||||
|
||||
- retry:
|
||||
first_instance = ret = snd_pcm_direct_shm_create_or_connect(dsnoop);
|
||||
if (ret < 0) {
|
||||
SNDERR("unable to create IPC shm instance");
|
||||
@@ -598,6 +597,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
||||
dsnoop->max_periods = opts->max_periods;
|
||||
dsnoop->sync_ptr = snd_pcm_dsnoop_sync_ptr;
|
||||
|
||||
+ retry:
|
||||
if (first_instance) {
|
||||
/* recursion is already checked in
|
||||
snd_pcm_direct_get_slave_ipc_offset() */
|
||||
--
|
||||
2.8.3
|
||||
|
@ -1,72 +0,0 @@
|
||||
From 6d1d620eadf32c6d963468ce56ff52cc3a2f32e2 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Wed, 25 May 2016 15:03:51 +0200
|
||||
Subject: [PATCH 12/15] pcm: dmix: resume workaround for buggy driver
|
||||
|
||||
The previous commit removed the whole handling of resume in dmix, but
|
||||
this seems causing another regression; some buggy drivers assume that
|
||||
the device-resume needs to be triggered before transitioning to
|
||||
PREPARED state. As an ugly workaround, in this patch, when the slave
|
||||
PCM supports resume, snd_pcm_direct_resume() does resume of the slave
|
||||
PCM but immediately drop the stream after that. In that way, the
|
||||
device is brought to the sane active state, then the apps can prepare
|
||||
and restart the stream properly.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 25 ++++++++++++++++++++++++-
|
||||
1 file changed, 24 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
|
||||
index 53c49929cb1f..343fd3c6da3c 100644
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -837,6 +837,27 @@ int snd_pcm_direct_prepare(snd_pcm_t *pcm)
|
||||
|
||||
int snd_pcm_direct_resume(snd_pcm_t *pcm)
|
||||
{
|
||||
+ snd_pcm_direct_t *dmix = pcm->private_data;
|
||||
+ snd_pcm_t *spcm = dmix->spcm;
|
||||
+
|
||||
+ snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||
+ /* some buggy drivers require the device resumed before prepared;
|
||||
+ * when a device has RESUME flag and is in SUSPENDED state, resume
|
||||
+ * here but immediately drop to bring it to a sane active state.
|
||||
+ */
|
||||
+ if ((spcm->info & SND_PCM_INFO_RESUME) &&
|
||||
+ snd_pcm_state(spcm) == SND_PCM_STATE_SUSPENDED) {
|
||||
+ snd_pcm_resume(spcm);
|
||||
+ snd_pcm_drop(spcm);
|
||||
+ snd_pcm_direct_timer_stop(dmix);
|
||||
+ snd_pcm_direct_clear_timer_queue(dmix);
|
||||
+ snd_pcm_areas_silence(snd_pcm_mmap_areas(spcm), 0,
|
||||
+ spcm->channels, spcm->buffer_size,
|
||||
+ spcm->format);
|
||||
+ snd_pcm_prepare(spcm);
|
||||
+ snd_pcm_start(spcm);
|
||||
+ }
|
||||
+ snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
@@ -845,7 +866,7 @@ int snd_pcm_direct_resume(snd_pcm_t *pcm)
|
||||
/* copy the slave setting */
|
||||
static void save_slave_setting(snd_pcm_direct_t *dmix, snd_pcm_t *spcm)
|
||||
{
|
||||
- spcm->info &= ~(SND_PCM_INFO_PAUSE | SND_PCM_INFO_RESUME);
|
||||
+ spcm->info &= ~SND_PCM_INFO_PAUSE;
|
||||
|
||||
COPY_SLAVE(access);
|
||||
COPY_SLAVE(format);
|
||||
@@ -874,6 +895,8 @@ static void save_slave_setting(snd_pcm_direct_t *dmix, snd_pcm_t *spcm)
|
||||
COPY_SLAVE(buffer_time);
|
||||
COPY_SLAVE(sample_bits);
|
||||
COPY_SLAVE(frame_bits);
|
||||
+
|
||||
+ dmix->shmptr->s.info &= ~SND_PCM_INFO_RESUME;
|
||||
}
|
||||
|
||||
#undef COPY_SLAVE
|
||||
--
|
||||
2.8.3
|
||||
|
@ -1,27 +0,0 @@
|
||||
From 8feb96ed9b457c2aa62ddea2c48651475b7c3411 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Tue, 31 May 2016 12:46:03 +0200
|
||||
Subject: [PATCH 13/15] pcm: dmix: Prepare slave when it's in SETUP, too
|
||||
|
||||
SETUP is an unusual state, but it's still possible.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
|
||||
index 343fd3c6da3c..fbf9a592a4bc 100644
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -819,6 +819,7 @@ int snd_pcm_direct_prepare(snd_pcm_t *pcm)
|
||||
int err;
|
||||
|
||||
switch (snd_pcm_state(dmix->spcm)) {
|
||||
+ case SND_PCM_STATE_SETUP:
|
||||
case SND_PCM_STATE_XRUN:
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
--
|
||||
2.8.3
|
||||
|
@ -1,37 +0,0 @@
|
||||
From 614ce73d3d6eba13946f863bec24981d355902e1 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Tue, 31 May 2016 12:48:40 +0200
|
||||
Subject: [PATCH 14/15] pcm: dmix: Return error when slave is in OPEN or
|
||||
DISCONNECTED
|
||||
|
||||
A slave PCM in OPEN or DISCONNECTED state can't be used properly at
|
||||
all, so the best option is to return -EBADFD error.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
|
||||
index fbf9a592a4bc..21f98e7a1779 100644
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -822,12 +822,14 @@ int snd_pcm_direct_prepare(snd_pcm_t *pcm)
|
||||
case SND_PCM_STATE_SETUP:
|
||||
case SND_PCM_STATE_XRUN:
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
- case SND_PCM_STATE_DISCONNECTED:
|
||||
err = snd_pcm_prepare(dmix->spcm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
snd_pcm_start(dmix->spcm);
|
||||
break;
|
||||
+ case SND_PCM_STATE_OPEN:
|
||||
+ case SND_PCM_STATE_DISCONNECTED:
|
||||
+ return -EBADFD;
|
||||
}
|
||||
snd_pcm_direct_check_interleave(dmix, pcm);
|
||||
dmix->state = SND_PCM_STATE_PREPARED;
|
||||
--
|
||||
2.8.3
|
||||
|
@ -1,84 +0,0 @@
|
||||
From d39e1879b9c72d51fe1ca4aeb5ba742e97b2175a Mon Sep 17 00:00:00 2001
|
||||
From: Eliot Miranda <eliot.miranda@gmail.com>
|
||||
Date: Wed, 1 Jun 2016 08:16:31 +0200
|
||||
Subject: [PATCH 15/15] async: Handle previously installed signal handler
|
||||
|
||||
The issue is with the signal handler installed and deinstalled in
|
||||
alsa-lib async handler. This code makes no attempt to remember any
|
||||
previously installed signal handlers for SIGIO, if SIGIO is used.
|
||||
Consequently it does not call any previous handlers from its own
|
||||
handler once installed, and does not reinstall any previous handler
|
||||
when deinstalling its handler. Consequently, use of also-lib within
|
||||
applications that depend on SIGIO will break those applications,
|
||||
rendering them inoperative once alsa-lib is running because their
|
||||
signal handlers are no longer called.
|
||||
|
||||
This patch does remember and restore any previous handler, and chains
|
||||
calls to the handler if it exists.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/async.c | 20 +++++++++++++-------
|
||||
1 file changed, 13 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/async.c b/src/async.c
|
||||
index 98aec78e00a8..0e133c3a34cd 100644
|
||||
--- a/src/async.c
|
||||
+++ b/src/async.c
|
||||
@@ -28,6 +28,9 @@
|
||||
#include "control/control_local.h"
|
||||
#include <signal.h>
|
||||
|
||||
+static struct sigaction previous_action;
|
||||
+#define MAX_SIG_FUNCTION_CODE 10 /* i.e. SIG_DFL SIG_IGN SIG_HOLD et al */
|
||||
+
|
||||
#ifdef SND_ASYNC_RT_SIGNAL
|
||||
/** async signal number */
|
||||
static int snd_async_signo;
|
||||
@@ -54,6 +57,9 @@ static void snd_async_handler(int signo ATTRIBUTE_UNUSED, siginfo_t *siginfo, vo
|
||||
int fd;
|
||||
struct list_head *i;
|
||||
//assert(siginfo->si_code == SI_SIGIO);
|
||||
+ if (signo == SIGIO
|
||||
+ && (unsigned long)(previous_action.sa_sigaction) > MAX_SIG_FUNCTION_CODE)
|
||||
+ previous_action.sa_sigaction(signo, siginfo, context);
|
||||
fd = siginfo->si_fd;
|
||||
list_for_each(i, &snd_async_handlers) {
|
||||
snd_async_handler_t *h = list_entry(i, snd_async_handler_t, glist);
|
||||
@@ -114,7 +120,8 @@ int snd_async_add_handler(snd_async_handler_t **handler, int fd,
|
||||
act.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
act.sa_sigaction = snd_async_handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
- err = sigaction(snd_async_signo, &act, NULL);
|
||||
+ assert(!previous_action.sa_sigaction);
|
||||
+ err = sigaction(snd_async_signo, &act, &previous_action);
|
||||
if (err < 0) {
|
||||
SYSERR("sigaction");
|
||||
return -errno;
|
||||
@@ -131,18 +138,17 @@ int snd_async_add_handler(snd_async_handler_t **handler, int fd,
|
||||
int snd_async_del_handler(snd_async_handler_t *handler)
|
||||
{
|
||||
int err = 0;
|
||||
+ int was_empty = list_empty(&snd_async_handlers);
|
||||
assert(handler);
|
||||
list_del(&handler->glist);
|
||||
- if (list_empty(&snd_async_handlers)) {
|
||||
- struct sigaction act;
|
||||
- memset(&act, 0, sizeof(act));
|
||||
- act.sa_flags = 0;
|
||||
- act.sa_handler = SIG_DFL;
|
||||
- err = sigaction(snd_async_signo, &act, NULL);
|
||||
+ if (!was_empty
|
||||
+ && list_empty(&snd_async_handlers)) {
|
||||
+ err = sigaction(snd_async_signo, &previous_action, NULL);
|
||||
if (err < 0) {
|
||||
SYSERR("sigaction");
|
||||
return -errno;
|
||||
}
|
||||
+ memset(&previous_action, 0, sizeof(previous_action));
|
||||
}
|
||||
if (handler->type == SND_ASYNC_HANDLER_GENERIC)
|
||||
goto _end;
|
||||
--
|
||||
2.8.3
|
||||
|
@ -1,12 +0,0 @@
|
||||
---
|
||||
doc/doxygen.cfg.in | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/doc/doxygen.cfg.in
|
||||
+++ b/doc/doxygen.cfg.in
|
||||
@@ -121,3 +121,5 @@ TYPEDEF_HIDES_STRUCT = YES # needed in d
|
||||
|
||||
#INPUT_FILTER = inputfilter
|
||||
#FILTER_SOURCE_FILES = YES
|
||||
+
|
||||
+HTML_TIMESTAMP = NO
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8ac76c3144ed2ed49da7622ab65ac5415205913ccbedde877972383cbc234269
|
||||
size 932105
|
3
alsa-lib-1.1.2.tar.bz2
Normal file
3
alsa-lib-1.1.2.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d38dacd9892b06b8bff04923c380b38fb2e379ee5538935ff37e45b395d861d6
|
||||
size 947423
|
36
alsa.changes
36
alsa.changes
@ -1,3 +1,39 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Aug 3 11:22:16 CEST 2016 - tiwai@suse.de
|
||||
|
||||
- Update to alsa-lib v1.1.2:
|
||||
* topology API updates
|
||||
* support of stacked async handlers
|
||||
* new UCM configs: rockchip-i2s, skylake-i2s, chtrt5645,
|
||||
* add cset-tlv ucm support
|
||||
* fix conversion of TLVs min_db and max_dB value in softvol
|
||||
* fix appl pointer in the error path of PCM plugin
|
||||
* PCM code cleanup
|
||||
* fix suspend/resume of PCM dmix, dsnoop and dshare plugins
|
||||
* fix doubly enumerated items via namehint
|
||||
* make PCM codes thread-safe
|
||||
* API documentation enhancements
|
||||
* element-set ctl API
|
||||
* Optimization by replacing alloca() usages
|
||||
|
||||
- Drop obsoleted patches:
|
||||
0001-pcm_plugin-fix-appl-pointer-not-correct-when-mmap_co.patch
|
||||
0002-pcm-Clean-up-error-paths-in-snd_pcm_plugin_-helpers.patch
|
||||
0003-pcm-Fallback-open-as-the-first-instance-for-dmix-co.patch
|
||||
0004-pcm-softvol-fix-conversion-of-TLVs-min_db-and-max_dB.patch
|
||||
0005-pcm-Fix-suspend-resume-regression-with-dmix-co.patch
|
||||
0006-pcm-dmix-Fix-doubly-resume-of-slave-PCM.patch
|
||||
0007-namehint-Don-t-enumerate-as-duplex-if-only-a-single-.patch
|
||||
0008-pcm-Define-namehint-for-single-directional-PCM-types.patch
|
||||
0009-conf-Add-thread-safe-global-tree-reference.patch
|
||||
0010-pcm-Remove-resume-support-from-dmix-co.patch
|
||||
0011-pcm-Fix-secondary-retry-in-dsnoop-and-dshare.patch
|
||||
0012-pcm-dmix-resume-workaround-for-buggy-driver.patch
|
||||
0013-pcm-dmix-Prepare-slave-when-it-s-in-SETUP-too.patch
|
||||
0014-pcm-dmix-Return-error-when-slave-is-in-OPEN-or-DISCO.patch
|
||||
0015-async-Handle-previously-installed-signal-handler.patch
|
||||
alsa-docs-suppress-timestamp.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jun 8 10:30:29 CEST 2016 - tiwai@suse.de
|
||||
|
||||
|
38
alsa.spec
38
alsa.spec
@ -16,16 +16,15 @@
|
||||
#
|
||||
|
||||
|
||||
%define package_version 1.1.1
|
||||
%define package_version 1.1.2
|
||||
%if 0%{?suse_version} > 1200
|
||||
%define _udevdir %(pkg-config --variable=udevdir udev)
|
||||
%else
|
||||
%define _udevdir /lib/udev
|
||||
%endif
|
||||
Name: alsa
|
||||
Version: 1.1.1
|
||||
Version: 1.1.2
|
||||
Release: 0
|
||||
#
|
||||
Summary: Advanced Linux Sound Architecture
|
||||
License: LGPL-2.1+
|
||||
Group: System/Libraries
|
||||
@ -49,25 +48,8 @@ Source40: 50-alsa.conf
|
||||
Source41: install-snd-module
|
||||
# Patch: alsa-lib-git-fixes.diff
|
||||
# upstream fixes
|
||||
Patch1: 0001-pcm_plugin-fix-appl-pointer-not-correct-when-mmap_co.patch
|
||||
Patch2: 0002-pcm-Clean-up-error-paths-in-snd_pcm_plugin_-helpers.patch
|
||||
Patch3: 0003-pcm-Fallback-open-as-the-first-instance-for-dmix-co.patch
|
||||
Patch4: 0004-pcm-softvol-fix-conversion-of-TLVs-min_db-and-max_dB.patch
|
||||
Patch5: 0005-pcm-Fix-suspend-resume-regression-with-dmix-co.patch
|
||||
Patch6: 0006-pcm-dmix-Fix-doubly-resume-of-slave-PCM.patch
|
||||
Patch7: 0007-namehint-Don-t-enumerate-as-duplex-if-only-a-single-.patch
|
||||
Patch8: 0008-pcm-Define-namehint-for-single-directional-PCM-types.patch
|
||||
Patch9: 0009-conf-Add-thread-safe-global-tree-reference.patch
|
||||
Patch10: 0010-pcm-Remove-resume-support-from-dmix-co.patch
|
||||
Patch11: 0011-pcm-Fix-secondary-retry-in-dsnoop-and-dshare.patch
|
||||
Patch12: 0012-pcm-dmix-resume-workaround-for-buggy-driver.patch
|
||||
Patch13: 0013-pcm-dmix-Prepare-slave-when-it-s-in-SETUP-too.patch
|
||||
Patch14: 0014-pcm-dmix-Return-error-when-slave-is-in-OPEN-or-DISCO.patch
|
||||
Patch15: 0015-async-Handle-previously-installed-signal-handler.patch
|
||||
# rest suse patches
|
||||
Patch99: alsa-lib-doxygen-avoid-crash-for-11.3.diff
|
||||
# suppress timestamp in documents
|
||||
Patch100: alsa-docs-suppress-timestamp.patch
|
||||
BuildRequires: doxygen
|
||||
BuildRequires: libtool
|
||||
BuildRequires: pkg-config
|
||||
@ -134,25 +116,9 @@ Architecture.
|
||||
%prep
|
||||
%setup -q -n alsa-lib-%{package_version}
|
||||
# %patch -p1
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%if 0%{?suse_version} == 1130
|
||||
%patch99 -p1
|
||||
%endif
|
||||
%patch100 -p1
|
||||
# hack to fix build on older distros
|
||||
%if 0%{?suse_version} < 1100
|
||||
%ifarch %{ix86}
|
||||
|
Loading…
x
Reference in New Issue
Block a user