Hello community, here is the log from the commit of package alsa for openSUSE:Factory checked in at 2016-05-19 12:03:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/alsa (Old) and /work/SRC/openSUSE:Factory/.alsa.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "alsa" Changes: -------- --- /work/SRC/openSUSE:Factory/alsa/alsa.changes 2016-04-05 10:41:45.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.alsa.new/alsa.changes 2016-05-19 12:03:36.000000000 +0200 @@ -1,0 +2,11 @@ +Thu May 12 14:44:48 CEST 2016 - [email protected] + +- Backport various upstream fixes for PCM (bnc#979702): + 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 + +------------------------------------------------------------------- New: ---- 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 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ alsa.spec ++++++ --- /var/tmp/diff_new_pack.R39uZC/_old 2016-05-19 12:03:38.000000000 +0200 +++ /var/tmp/diff_new_pack.R39uZC/_new 2016-05-19 12:03:38.000000000 +0200 @@ -49,6 +49,12 @@ 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 # rest suse patches Patch99: alsa-lib-doxygen-avoid-crash-for-11.3.diff # suppress timestamp in documents @@ -119,6 +125,12 @@ %prep %setup -q -n alsa-lib-%{package_version} # %patch -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 %if 0%{?suse_version} == 1130 %patch99 -p1 %endif ++++++ 0001-pcm_plugin-fix-appl-pointer-not-correct-when-mmap_co.patch ++++++ >From 7c424edd116e76eee6218a1e9a6ff6c4daaf2a4d Mon Sep 17 00:00:00 2001 From: Shengjiu Wang <[email protected]> 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 <[email protected]> Signed-off-by: Takashi Iwai <[email protected]> --- 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 ++++++ 0002-pcm-Clean-up-error-paths-in-snd_pcm_plugin_-helpers.patch ++++++ >From 503a285ed60164d8c65c6ee9ba6f23631da753df Mon Sep 17 00:00:00 2001 From: Takashi Iwai <[email protected]> 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 <[email protected]> --- 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 ++++++ 0003-pcm-Fallback-open-as-the-first-instance-for-dmix-co.patch ++++++ >From fdba9e1bad8f769a6137e565471f0227f23a3132 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <[email protected]> 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 <[email protected]> Signed-off-by: Takashi Iwai <[email protected]> --- 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 ++++++ 0004-pcm-softvol-fix-conversion-of-TLVs-min_db-and-max_dB.patch ++++++ >From 85bf9915989e0a338632739684c75192c1753239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Krause?= <[email protected]> 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 <[email protected]> Signed-off-by: Jörg Krause <[email protected]> Signed-off-by: Takashi Iwai <[email protected]> --- 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 ++++++ 0005-pcm-Fix-suspend-resume-regression-with-dmix-co.patch ++++++ >From c14b0a08f0bf58e4f62307c68f8ff0137b4dec19 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <[email protected]> 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 <[email protected]> Signed-off-by: Takashi Iwai <[email protected]> --- 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 ++++++ 0006-pcm-dmix-Fix-doubly-resume-of-slave-PCM.patch ++++++ >From 5610b356b5f110f7f8e586f56e5b74e0f0c2db38 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <[email protected]> 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 <[email protected]> --- 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
