- Backport upstream fixes: fixing PCM dmix & co suspend/resume, namehint parser fixes, stackable async handler: 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/400689 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=198
73 lines
2.5 KiB
Diff
73 lines
2.5 KiB
Diff
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
|
|
|