Blame SOURCES/alsa-git.patch

d099e2
From 63ba5243ab7a33b77be5b65c0a8a2a0d5e26983f Mon Sep 17 00:00:00 2001
d099e2
From: Vanitha Channaiah <vanitha.channaiah@in.bosch.com>
d099e2
Date: Wed, 15 May 2019 11:56:32 +0530
d099e2
Subject: [PATCH 01/25] pcm: direct: Add generic hw_ptr_alignment function for
d099e2
 dmix, dshare and dsnoop
d099e2
d099e2
Move the code snd_pcm_direct_reset_slave_ptr() from pcm_dmix.c
d099e2
to pcm_direct.c and its header so that the helper function can be
d099e2
re-used by other direct-pcm plugins.
d099e2
There is no change in the behavior or the functionality.
d099e2
d099e2
Signed-off-by: Vanitha Channaiah <vanitha.channaiah@in.bosch.com>
d099e2
Signed-off-by: Takashi Iwai <tiwai@suse.de>
d099e2
---
d099e2
 src/pcm/pcm_direct.c | 19 +++++++++++++++++++
d099e2
 src/pcm/pcm_direct.h |  8 ++++++++
d099e2
 src/pcm/pcm_dmix.c   | 25 ++-----------------------
d099e2
 3 files changed, 29 insertions(+), 23 deletions(-)
d099e2
d099e2
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
d099e2
index 666a8ce5..411a035b 100644
d099e2
--- a/src/pcm/pcm_direct.c
d099e2
+++ b/src/pcm/pcm_direct.c
d099e2
@@ -2040,3 +2040,22 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
d099e2
 
d099e2
 	return 0;
d099e2
 }
d099e2
+
d099e2
+void snd_pcm_direct_reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix)
d099e2
+{
d099e2
+	dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
d099e2
+
d099e2
+	if (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_ROUNDUP ||
d099e2
+		(dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_AUTO &&
d099e2
+		pcm->buffer_size <= pcm->period_size * 2))
d099e2
+		dmix->slave_appl_ptr =
d099e2
+			((dmix->slave_appl_ptr + dmix->slave_period_size - 1) /
d099e2
+			dmix->slave_period_size) * dmix->slave_period_size;
d099e2
+	else if (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_ROUNDDOWN ||
d099e2
+		(dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_AUTO &&
d099e2
+		(dmix->slave_period_size * SEC_TO_MS) /
d099e2
+		pcm->rate < LOW_LATENCY_PERIOD_TIME))
d099e2
+		dmix->slave_appl_ptr = dmix->slave_hw_ptr =
d099e2
+			((dmix->slave_hw_ptr / dmix->slave_period_size) *
d099e2
+			dmix->slave_period_size);
d099e2
+}
d099e2
diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h
d099e2
index da5e280e..a71aab13 100644
d099e2
--- a/src/pcm/pcm_direct.h
d099e2
+++ b/src/pcm/pcm_direct.h
d099e2
@@ -24,6 +24,11 @@
d099e2
 
d099e2
 #define DIRECT_IPC_SEMS         1
d099e2
 #define DIRECT_IPC_SEM_CLIENT   0
d099e2
+/* Seconds representing in Milli seconds */
d099e2
+#define SEC_TO_MS               1000
d099e2
+/* slave_period time for low latency requirements in ms */
d099e2
+#define LOW_LATENCY_PERIOD_TIME 10
d099e2
+
d099e2
 
d099e2
 typedef void (mix_areas_t)(unsigned int size,
d099e2
 			   volatile void *dst, void *src,
d099e2
@@ -257,6 +262,8 @@ struct snd_pcm_direct {
d099e2
 	snd1_pcm_direct_get_chmap
d099e2
 #define snd_pcm_direct_set_chmap \
d099e2
 	snd1_pcm_direct_set_chmap
d099e2
+#define snd_pcm_direct_reset_slave_ptr \
d099e2
+	snd1_pcm_direct_reset_slave_ptr
d099e2
 
d099e2
 int snd_pcm_direct_semaphore_create_or_connect(snd_pcm_direct_t *dmix);
d099e2
 
d099e2
@@ -341,6 +348,7 @@ int snd_pcm_direct_slave_recover(snd_pcm_direct_t *direct);
d099e2
 int snd_pcm_direct_client_chk_xrun(snd_pcm_direct_t *direct, snd_pcm_t *pcm);
d099e2
 int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid);
d099e2
 struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm);
d099e2
+void snd_pcm_direct_reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix);
d099e2
 
d099e2
 struct snd_pcm_direct_open_conf {
d099e2
 	key_t ipc_key;
d099e2
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
d099e2
index c5592cdb..dcde40d9 100644
d099e2
--- a/src/pcm/pcm_dmix.c
d099e2
+++ b/src/pcm/pcm_dmix.c
d099e2
@@ -55,9 +55,6 @@ const char *_snd_module_pcm_dmix = "";
d099e2
 #define STATE_RUN_PENDING	1024
d099e2
 #endif
d099e2
 
d099e2
-#define SEC_TO_MS	1000			/* Seconds representing in Milli seconds */
d099e2
-#define LOW_LATENCY_PERIOD_TIME	10	/* slave_period time for low latency requirements in ms */
d099e2
-
d099e2
 /*
d099e2
  *
d099e2
  */
d099e2
@@ -560,30 +557,12 @@ static int snd_pcm_dmix_hwsync(snd_pcm_t *pcm)
d099e2
 	}
d099e2
 }
d099e2
 
d099e2
-static void reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix)
d099e2
-{
d099e2
-	dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
d099e2
-
d099e2
-	if (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_ROUNDUP ||
d099e2
-	    (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_AUTO &&
d099e2
-	     pcm->buffer_size <= pcm->period_size * 2))
d099e2
-		dmix->slave_appl_ptr =
d099e2
-			((dmix->slave_appl_ptr + dmix->slave_period_size - 1)
d099e2
-			 / dmix->slave_period_size) * dmix->slave_period_size;
d099e2
-	else if (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_ROUNDDOWN ||
d099e2
-		 (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_AUTO &&
d099e2
-		  (dmix->slave_period_size * SEC_TO_MS) / pcm->rate < LOW_LATENCY_PERIOD_TIME))
d099e2
-		dmix->slave_appl_ptr = dmix->slave_hw_ptr =
d099e2
-			((dmix->slave_hw_ptr / dmix->slave_period_size) *
d099e2
-			 dmix->slave_period_size);
d099e2
-}
d099e2
-
d099e2
 static int snd_pcm_dmix_reset(snd_pcm_t *pcm)
d099e2
 {
d099e2
 	snd_pcm_direct_t *dmix = pcm->private_data;
d099e2
 	dmix->hw_ptr %= pcm->period_size;
d099e2
 	dmix->appl_ptr = dmix->last_appl_ptr = dmix->hw_ptr;
d099e2
-	reset_slave_ptr(pcm, dmix);
d099e2
+	snd_pcm_direct_reset_slave_ptr(pcm, dmix);
d099e2
 	return 0;
d099e2
 }
d099e2
 
d099e2
@@ -592,7 +571,7 @@ static int snd_pcm_dmix_start_timer(snd_pcm_t *pcm, snd_pcm_direct_t *dmix)
d099e2
 	int err;
d099e2
 
d099e2
 	snd_pcm_hwsync(dmix->spcm);
d099e2
-	reset_slave_ptr(pcm, dmix);
d099e2
+	snd_pcm_direct_reset_slave_ptr(pcm, dmix);
d099e2
 	err = snd_timer_start(dmix->timer);
d099e2
 	if (err < 0)
d099e2
 		return err;
d099e2
-- 
d099e2
2.20.1
d099e2
d099e2
d099e2
From 7265e603bf880a9ec2cd01c3cf2afbd7709e5af4 Mon Sep 17 00:00:00 2001
d099e2
From: Vanitha Channaiah <vanitha.channaiah@in.bosch.com>
d099e2
Date: Wed, 15 May 2019 11:56:33 +0530
d099e2
Subject: [PATCH 02/25] pcm: dshare: Added "hw_ptr_alignment" option in
d099e2
 configuration for alignment of slave pointers
d099e2
d099e2
This change adapt the fix commit 6b058fda9dce
d099e2
("pcm: dmix: Add option to allow alignment of slave pointers")
d099e2
for dshare plugin
d099e2
d099e2
Issue is that snd_pcm_wait() goes back to waiting because the hw_ptr
d099e2
is not period aligned. Therefore snd_pcm_wait() will block for a longer
d099e2
time as required.
d099e2
d099e2
With these rcar driver changes the exact position of the dma is returned.
d099e2
During snd_pcm_start they read hw_ptr as reference, and this hw_ptr
d099e2
is now not period aligned, and is a little ahead over the period while it
d099e2
is read. Therefore when the avail is calculated during snd_pcm_wait(),
d099e2
it is missing the avail_min by a few frames.
d099e2
d099e2
An additional option hw_ptr_alignment is provided to dshare configuration,
d099e2
to allow the user to configure the slave application and hw pointer
d099e2
alignment at startup
d099e2
d099e2
Signed-off-by: Vanitha Channaiah <vanitha.channaiah@in.bosch.com>
d099e2
Signed-off-by: Takashi Iwai <tiwai@suse.de>
d099e2
---
d099e2
 src/pcm/pcm_dshare.c | 40 +++++++++++++++++++++++++++++++++++-----
d099e2
 1 file changed, 35 insertions(+), 5 deletions(-)
d099e2
d099e2
diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
d099e2
index f135b5df..cf8a8631 100644
d099e2
--- a/src/pcm/pcm_dshare.c
d099e2
+++ b/src/pcm/pcm_dshare.c
d099e2
@@ -333,16 +333,16 @@ static int snd_pcm_dshare_reset(snd_pcm_t *pcm)
d099e2
 	snd_pcm_direct_t *dshare = pcm->private_data;
d099e2
 	dshare->hw_ptr %= pcm->period_size;
d099e2
 	dshare->appl_ptr = dshare->last_appl_ptr = dshare->hw_ptr;
d099e2
-	dshare->slave_appl_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr;
d099e2
+	snd_pcm_direct_reset_slave_ptr(pcm, dshare);
d099e2
 	return 0;
d099e2
 }
d099e2
 
d099e2
-static int snd_pcm_dshare_start_timer(snd_pcm_direct_t *dshare)
d099e2
+static int snd_pcm_dshare_start_timer(snd_pcm_t *pcm, snd_pcm_direct_t *dshare)
d099e2
 {
d099e2
 	int err;
d099e2
 
d099e2
 	snd_pcm_hwsync(dshare->spcm);
d099e2
-	dshare->slave_appl_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr;
d099e2
+	snd_pcm_direct_reset_slave_ptr(pcm, dshare);
d099e2
 	err = snd_timer_start(dshare->timer);
d099e2
 	if (err < 0)
d099e2
 		return err;
d099e2
@@ -364,7 +364,8 @@ static int snd_pcm_dshare_start(snd_pcm_t *pcm)
d099e2
 	else if (avail < 0)
d099e2
 		return 0;
d099e2
 	else {
d099e2
-		if ((err = snd_pcm_dshare_start_timer(dshare)) < 0)
d099e2
+		err = snd_pcm_dshare_start_timer(pcm, dshare);
d099e2
+		if (err < 0)
d099e2
 			return err;
d099e2
 		snd_pcm_dshare_sync_area(pcm);
d099e2
 	}
d099e2
@@ -547,7 +548,8 @@ static snd_pcm_sframes_t snd_pcm_dshare_mmap_commit(snd_pcm_t *pcm,
d099e2
 		return 0;
d099e2
 	snd_pcm_mmap_appl_forward(pcm, size);
d099e2
 	if (dshare->state == STATE_RUN_PENDING) {
d099e2
-		if ((err = snd_pcm_dshare_start_timer(dshare)) < 0)
d099e2
+		err = snd_pcm_dshare_start_timer(pcm, dshare);
d099e2
+		if (err < 0)
d099e2
 			return err;
d099e2
 	} else if (dshare->state == SND_PCM_STATE_RUNNING ||
d099e2
 		   dshare->state == SND_PCM_STATE_DRAINING) {
d099e2
@@ -755,6 +757,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
d099e2
 	dshare->slowptr = opts->slowptr;
d099e2
 	dshare->max_periods = opts->max_periods;
d099e2
 	dshare->var_periodsize = opts->var_periodsize;
d099e2
+	dshare->hw_ptr_alignment = opts->hw_ptr_alignment;
d099e2
 	dshare->sync_ptr = snd_pcm_dshare_sync_ptr;
d099e2
 
d099e2
  retry:
d099e2
@@ -912,6 +915,12 @@ pcm.name {
d099e2
 	ipc_key INT		# unique IPC key
d099e2
 	ipc_key_add_uid BOOL	# add current uid to unique IPC key
d099e2
 	ipc_perm INT		# IPC permissions (octal, default 0600)
d099e2
+	hw_ptr_alignment STR	# Slave application and hw pointer alignment type
d099e2
+		# STR can be one of the below strings :
d099e2
+		# no
d099e2
+		# roundup
d099e2
+		# rounddown
d099e2
+		# auto (default)
d099e2
 	slave STR
d099e2
 	# or
d099e2
 	slave {			# Slave definition
d099e2
@@ -936,6 +945,27 @@ pcm.name {
d099e2
 }
d099e2
 \endcode
d099e2
 
d099e2
+hw_ptr_alignment specifies slave application and hw
d099e2
+pointer alignment type. By default hw_ptr_alignment is auto. Below are
d099e2
+the possible configurations:
d099e2
+- no: minimal latency with minimal frames dropped at startup. But
d099e2
+  wakeup of application (return from snd_pcm_wait() or poll()) can
d099e2
+  take up to 2 * period.
d099e2
+- roundup: It is guaranteed that all frames will be played at
d099e2
+  startup. But the latency will increase upto period-1 frames.
d099e2
+- rounddown: It is guaranteed that a wakeup will happen for each
d099e2
+  period and frames can be written from application. But on startup
d099e2
+  upto period-1 frames will be dropped.
d099e2
+- auto: Selects the best approach depending on the used period and
d099e2
+  buffer size.
d099e2
+  If the application buffer size is < 2 * application period,
d099e2
+  "roundup" will be selected to avoid under runs. If the slave_period
d099e2
+  is < 10ms we could expect that there are low latency
d099e2
+  requirements. Therefore "rounddown" will be chosen to avoid long
d099e2
+  wakeup times. Such wakeup delay could otherwise end up with Xruns in
d099e2
+  case of a dependency to another sound device (e.g. forwarding of
d099e2
+  microphone to speaker). Else "no" will be chosen.
d099e2
+
d099e2
 \subsection pcm_plugins_dshare_funcref Function reference
d099e2
 
d099e2
 
    d099e2
    -- 
    d099e2
    2.20.1
    d099e2
    d099e2
    d099e2
    From 3ab798004733ce65bd5c7a48d650de3465825210 Mon Sep 17 00:00:00 2001
    d099e2
    From: Vanitha Channaiah <vanitha.channaiah@in.bosch.com>
    d099e2
    Date: Wed, 15 May 2019 11:56:34 +0530
    d099e2
    Subject: [PATCH 03/25] pcm: dsnoop: Added "hw_ptr_alignment" option in
    d099e2
     configuration for slave pointer alignment
    d099e2
    d099e2
    This change adapt the fix commit 6b058fda9dce
    d099e2
    ("pcm: dmix: Add option to allow alignment of slave pointers")
    d099e2
    for dsnoop plugin
    d099e2
    d099e2
    Issue is that snd_pcm_wait() goes back to waiting because the hw_ptr
    d099e2
    is not period aligned. Therefore snd_pcm_wait() will block for a longer
    d099e2
    time as required.
    d099e2
    d099e2
    With these rcar driver changes the exact position of the dma is returned.
    d099e2
    During snd_pcm_start they read hw_ptr as reference, and this hw_ptr
    d099e2
    is now not period aligned, and is a little ahead over the period while it
    d099e2
    is read. Therefore when the avail is calculated during snd_pcm_wait(),
    d099e2
    it is missing the avail_min by a few frames.
    d099e2
    d099e2
    An additional option hw_ptr_alignment is provided to dsnoop configuration,
    d099e2
    to allow the user to configure the slave application and hw pointer
    d099e2
    alignment at startup
    d099e2
    d099e2
    Signed-off-by: Vanitha Channaiah <vanitha.channaiah@in.bosch.com>
    d099e2
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    d099e2
    ---
    d099e2
     src/pcm/pcm_direct.c |  1 -
    d099e2
     src/pcm/pcm_dmix.c   |  2 ++
    d099e2
     src/pcm/pcm_dshare.c |  2 ++
    d099e2
     src/pcm/pcm_dsnoop.c | 30 +++++++++++++++++++++++++++++-
    d099e2
     4 files changed, 33 insertions(+), 2 deletions(-)
    d099e2
    d099e2
    diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
    d099e2
    index 411a035b..54d99005 100644
    d099e2
    --- a/src/pcm/pcm_direct.c
    d099e2
    +++ b/src/pcm/pcm_direct.c
    d099e2
    @@ -2043,7 +2043,6 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
    d099e2
     
    d099e2
     void snd_pcm_direct_reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix)
    d099e2
     {
    d099e2
    -	dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
    d099e2
     
    d099e2
     	if (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_ROUNDUP ||
    d099e2
     		(dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_AUTO &&
    d099e2
    diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
    d099e2
    index dcde40d9..274726e4 100644
    d099e2
    --- a/src/pcm/pcm_dmix.c
    d099e2
    +++ b/src/pcm/pcm_dmix.c
    d099e2
    @@ -562,6 +562,7 @@ static int snd_pcm_dmix_reset(snd_pcm_t *pcm)
    d099e2
     	snd_pcm_direct_t *dmix = pcm->private_data;
    d099e2
     	dmix->hw_ptr %= pcm->period_size;
    d099e2
     	dmix->appl_ptr = dmix->last_appl_ptr = dmix->hw_ptr;
    d099e2
    +	dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
    d099e2
     	snd_pcm_direct_reset_slave_ptr(pcm, dmix);
    d099e2
     	return 0;
    d099e2
     }
    d099e2
    @@ -571,6 +572,7 @@ static int snd_pcm_dmix_start_timer(snd_pcm_t *pcm, snd_pcm_direct_t *dmix)
    d099e2
     	int err;
    d099e2
     
    d099e2
     	snd_pcm_hwsync(dmix->spcm);
    d099e2
    +	dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
    d099e2
     	snd_pcm_direct_reset_slave_ptr(pcm, dmix);
    d099e2
     	err = snd_timer_start(dmix->timer);
    d099e2
     	if (err < 0)
    d099e2
    diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
    d099e2
    index cf8a8631..b75809c8 100644
    d099e2
    --- a/src/pcm/pcm_dshare.c
    d099e2
    +++ b/src/pcm/pcm_dshare.c
    d099e2
    @@ -333,6 +333,7 @@ static int snd_pcm_dshare_reset(snd_pcm_t *pcm)
    d099e2
     	snd_pcm_direct_t *dshare = pcm->private_data;
    d099e2
     	dshare->hw_ptr %= pcm->period_size;
    d099e2
     	dshare->appl_ptr = dshare->last_appl_ptr = dshare->hw_ptr;
    d099e2
    +	dshare->slave_appl_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr;
    d099e2
     	snd_pcm_direct_reset_slave_ptr(pcm, dshare);
    d099e2
     	return 0;
    d099e2
     }
    d099e2
    @@ -342,6 +343,7 @@ static int snd_pcm_dshare_start_timer(snd_pcm_t *pcm, snd_pcm_direct_t *dshare)
    d099e2
     	int err;
    d099e2
     
    d099e2
     	snd_pcm_hwsync(dshare->spcm);
    d099e2
    +	dshare->slave_appl_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr;
    d099e2
     	snd_pcm_direct_reset_slave_ptr(pcm, dshare);
    d099e2
     	err = snd_timer_start(dshare->timer);
    d099e2
     	if (err < 0)
    d099e2
    diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
    d099e2
    index d08b6241..58b1e534 100644
    d099e2
    --- a/src/pcm/pcm_dsnoop.c
    d099e2
    +++ b/src/pcm/pcm_dsnoop.c
    d099e2
    @@ -278,6 +278,7 @@ static int snd_pcm_dsnoop_reset(snd_pcm_t *pcm)
    d099e2
     	dsnoop->hw_ptr %= pcm->period_size;
    d099e2
     	dsnoop->appl_ptr = dsnoop->hw_ptr;
    d099e2
     	dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr;
    d099e2
    +	snd_pcm_direct_reset_slave_ptr(pcm, dsnoop);
    d099e2
     	return 0;
    d099e2
     }
    d099e2
     
    d099e2
    @@ -285,12 +286,13 @@ static int snd_pcm_dsnoop_start(snd_pcm_t *pcm)
    d099e2
     {
    d099e2
     	snd_pcm_direct_t *dsnoop = pcm->private_data;
    d099e2
     	int err;
    d099e2
    -	
    d099e2
    +
    d099e2
     	if (dsnoop->state != SND_PCM_STATE_PREPARED)
    d099e2
     		return -EBADFD;
    d099e2
     	snd_pcm_hwsync(dsnoop->spcm);
    d099e2
     	snoop_timestamp(pcm);
    d099e2
     	dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr;
    d099e2
    +	snd_pcm_direct_reset_slave_ptr(pcm, dsnoop);
    d099e2
     	err = snd_timer_start(dsnoop->timer);
    d099e2
     	if (err < 0)
    d099e2
     		return err;
    d099e2
    @@ -627,6 +629,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
    d099e2
     	dsnoop->max_periods = opts->max_periods;
    d099e2
     	dsnoop->var_periodsize = opts->var_periodsize;
    d099e2
     	dsnoop->sync_ptr = snd_pcm_dsnoop_sync_ptr;
    d099e2
    +	dsnoop->hw_ptr_alignment = opts->hw_ptr_alignment;
    d099e2
     
    d099e2
      retry:
    d099e2
     	if (first_instance) {
    d099e2
    @@ -771,6 +774,12 @@ pcm.name {
    d099e2
     	ipc_key INT		# unique IPC key
    d099e2
     	ipc_key_add_uid BOOL	# add current uid to unique IPC key
    d099e2
     	ipc_perm INT		# IPC permissions (octal, default 0600)
    d099e2
    +	hw_ptr_alignment STR	# Slave application and hw pointer alignment type
    d099e2
    +		# STR can be one of the below strings :
    d099e2
    +		# no
    d099e2
    +		# roundup
    d099e2
    +		# rounddown
    d099e2
    +		# auto (default)
    d099e2
     	slave STR
    d099e2
     	# or
    d099e2
     	slave {			# Slave definition
    d099e2
    @@ -795,6 +804,25 @@ pcm.name {
    d099e2
     }
    d099e2
     \endcode
    d099e2
     
    d099e2
    +hw_ptr_alignment specifies slave application and hw
    d099e2
    +pointer alignment type. By default hw_ptr_alignment is auto. Below are
    d099e2
    +the possible configurations:
    d099e2
    +- no: minimal latency with minimal frames dropped at startup. But
    d099e2
    +  wakeup of application (return from snd_pcm_wait() or poll()) can
    d099e2
    +  take up to 2 * period.
    d099e2
    +- roundup: It is guaranteed that all frames will be played at
    d099e2
    +  startup. But the latency will increase upto period-1 frames.
    d099e2
    +- rounddown: It is guaranteed that a wakeup will happen for each
    d099e2
    +  period and frames can be written from application. But on startup
    d099e2
    +  upto period-1 frames will be dropped.
    d099e2
    +- auto: Selects the best approach depending on the used period and
    d099e2
    +  buffer size.
    d099e2
    +  If the application buffer size is < 2 * application period,
    d099e2
    +  "roundup" will be selected to avoid over runs. If the slave_period
    d099e2
    +  is < 10ms we could expect that there are low latency
    d099e2
    +  requirements. Therefore "rounddown" will be chosen to avoid long
    d099e2
    +  wakeup times. Else "no" will be chosen.
    d099e2
    +
    d099e2
     \subsection pcm_plugins_dsnoop_funcref Function reference
    d099e2
     
    d099e2
     
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 5f2e5af61b0b8cfbf310e8b1e08a034d993e432f Mon Sep 17 00:00:00 2001
      d099e2
      From: Adam Miartus <amiartus@de.adit-jv.com>
      d099e2
      Date: Tue, 21 May 2019 15:32:47 +0200
      d099e2
      Subject: [PATCH 04/25] pcm: file: add support for infile reading in non
      d099e2
       interleaved mode
      d099e2
      d099e2
      add helper function to copy input file data to buffer mapped by areas,
      d099e2
      in case of an error, do not fill the areas, allowing device read buffer
      d099e2
      to be provided to api caller
      d099e2
      d099e2
      previously unused rbuf variable is reused for this purpose
      d099e2
      d099e2
      Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
      d099e2
      Reviewed-by: Timo Wischer <twischer@de.adit-jv.com>
      d099e2
      Signed-off-by: Takashi Iwai <tiwai@suse.de>
      d099e2
      ---
      d099e2
       src/pcm/pcm_file.c | 67 ++++++++++++++++++++++++++++++++++++++--------
      d099e2
       1 file changed, 56 insertions(+), 11 deletions(-)
      d099e2
      d099e2
      diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
      d099e2
      index 3a19cef9..3c682659 100644
      d099e2
      --- a/src/pcm/pcm_file.c
      d099e2
      +++ b/src/pcm/pcm_file.c
      d099e2
      @@ -77,6 +77,7 @@ typedef struct {
      d099e2
       	snd_pcm_uframes_t appl_ptr;
      d099e2
       	snd_pcm_uframes_t file_ptr_bytes;
      d099e2
       	snd_pcm_uframes_t wbuf_size;
      d099e2
      +	snd_pcm_uframes_t rbuf_size;
      d099e2
       	size_t wbuf_size_bytes;
      d099e2
       	size_t wbuf_used_bytes;
      d099e2
       	char *wbuf;
      d099e2
      @@ -266,6 +267,39 @@ static int snd_pcm_file_open_output_file(snd_pcm_file_t *file)
      d099e2
       	return 0;
      d099e2
       }
      d099e2
       
      d099e2
      +/* fill areas with data from input file, return bytes red */
      d099e2
      +static int snd_pcm_file_areas_read_infile(snd_pcm_t *pcm,
      d099e2
      +					  const snd_pcm_channel_area_t *areas,
      d099e2
      +					  snd_pcm_uframes_t offset,
      d099e2
      +					  snd_pcm_uframes_t frames)
      d099e2
      +{
      d099e2
      +	snd_pcm_file_t *file = pcm->private_data;
      d099e2
      +	snd_pcm_channel_area_t areas_if[pcm->channels];
      d099e2
      +	ssize_t bytes;
      d099e2
      +
      d099e2
      +	if (file->ifd < 0)
      d099e2
      +		return -EBADF;
      d099e2
      +
      d099e2
      +	if (file->rbuf == NULL)
      d099e2
      +		return -ENOMEM;
      d099e2
      +
      d099e2
      +	if (file->rbuf_size < frames) {
      d099e2
      +		SYSERR("requested more frames than pcm buffer");
      d099e2
      +		return -ENOMEM;
      d099e2
      +	}
      d099e2
      +
      d099e2
      +	bytes = read(file->ifd, file->rbuf, snd_pcm_frames_to_bytes(pcm, frames));
      d099e2
      +	if (bytes < 0) {
      d099e2
      +		SYSERR("read from file failed, error: %d", bytes);
      d099e2
      +		return bytes;
      d099e2
      +	}
      d099e2
      +
      d099e2
      +	snd_pcm_areas_from_buf(pcm, areas_if, file->rbuf);
      d099e2
      +	snd_pcm_areas_copy(areas, offset, areas_if, 0, pcm->channels, snd_pcm_bytes_to_frames(pcm, bytes), pcm->format);
      d099e2
      +
      d099e2
      +	return bytes;
      d099e2
      +}
      d099e2
      +
      d099e2
       static void setup_wav_header(snd_pcm_t *pcm, struct wav_fmt *fmt)
      d099e2
       {
      d099e2
       	fmt->fmt = TO_LE16(0x01);
      d099e2
      @@ -568,19 +602,19 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm
      d099e2
       {
      d099e2
       	snd_pcm_file_t *file = pcm->private_data;
      d099e2
       	snd_pcm_channel_area_t areas[pcm->channels];
      d099e2
      -	snd_pcm_sframes_t n;
      d099e2
      +	snd_pcm_sframes_t frames;
      d099e2
       
      d099e2
      -	if (file->ifd >= 0) {
      d099e2
      -		SNDERR("DEBUG: Noninterleaved read not yet implemented.\n");
      d099e2
      -		return 0;	/* TODO: Noninterleaved read */
      d099e2
      -	}
      d099e2
      +	__snd_pcm_lock(pcm);
      d099e2
      +	frames = _snd_pcm_readn(file->gen.slave, bufs, size);
      d099e2
      +	if (frames <= 0)
      d099e2
      +		return frames;
      d099e2
       
      d099e2
      -	n = _snd_pcm_readn(file->gen.slave, bufs, size);
      d099e2
      -	if (n > 0) {
      d099e2
      -		snd_pcm_areas_from_bufs(pcm, areas, bufs);
      d099e2
      -		snd_pcm_file_add_frames(pcm, areas, 0, n);
      d099e2
      -	}
      d099e2
      -	return n;
      d099e2
      +	snd_pcm_areas_from_bufs(pcm, areas, bufs);
      d099e2
      +	snd_pcm_file_areas_read_infile(pcm, areas, 0, frames);
      d099e2
      +	snd_pcm_file_add_frames(pcm, areas, 0, frames);
      d099e2
      +
      d099e2
      +	__snd_pcm_unlock(pcm);
      d099e2
      +	return frames;
      d099e2
       }
      d099e2
       
      d099e2
       static snd_pcm_sframes_t snd_pcm_file_mmap_commit(snd_pcm_t *pcm,
      d099e2
      @@ -609,9 +643,11 @@ static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
      d099e2
       	free(file->wbuf);
      d099e2
       	free(file->wbuf_areas);
      d099e2
       	free(file->final_fname);
      d099e2
      +	free(file->rbuf);
      d099e2
       	file->wbuf = NULL;
      d099e2
       	file->wbuf_areas = NULL;
      d099e2
       	file->final_fname = NULL;
      d099e2
      +	file->rbuf = NULL;
      d099e2
       	return snd_pcm_hw_free(file->gen.slave);
      d099e2
       }
      d099e2
       
      d099e2
      @@ -638,6 +674,15 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
      d099e2
       		snd_pcm_file_hw_free(pcm);
      d099e2
       		return -ENOMEM;
      d099e2
       	}
      d099e2
      +	assert(!file->rbuf);
      d099e2
      +	file->rbuf_size = slave->buffer_size;
      d099e2
      +	file->rbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->rbuf_size);
      d099e2
      +	file->rbuf_used_bytes = 0;
      d099e2
      +	file->rbuf = malloc(file->rbuf_size_bytes);
      d099e2
      +	if (file->rbuf == NULL) {
      d099e2
      +		snd_pcm_file_hw_free(pcm);
      d099e2
      +		return -ENOMEM;
      d099e2
      +	}
      d099e2
       	file->appl_ptr = file->file_ptr_bytes = 0;
      d099e2
       	for (channel = 0; channel < slave->channels; ++channel) {
      d099e2
       		snd_pcm_channel_area_t *a = &file->wbuf_areas[channel];
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 349b42f5477c904fa3e10bac2fa2429fad2cbc65 Mon Sep 17 00:00:00 2001
      d099e2
      From: Adam Miartus <amiartus@de.adit-jv.com>
      d099e2
      Date: Tue, 21 May 2019 15:33:08 +0200
      d099e2
      Subject: [PATCH 05/25] pcm: file: use snd_pcm_file_areas_read_infile for readi
      d099e2
      d099e2
      use previously introduced helper function, this commit unifies behavior
      d099e2
      of readi and readn
      d099e2
      d099e2
      corner case behavior of readi is changed by this commit, previously,
      d099e2
      in case 0 bytes were red from file (EOF), frames = 0 was returned,
      d099e2
      signaling api user as if no data was red from slave, after the patch,
      d099e2
      amount of frames red from slave with data red from slave stored in buffer
      d099e2
      is returned when EOF is reached
      d099e2
      d099e2
      Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
      d099e2
      Reviewed-by: Timo Wischer <twischer@de.adit-jv.com>
      d099e2
      Signed-off-by: Takashi Iwai <tiwai@suse.de>
      d099e2
      ---
      d099e2
       src/pcm/pcm_file.c | 27 +++++++++++++--------------
      d099e2
       1 file changed, 13 insertions(+), 14 deletions(-)
      d099e2
      d099e2
      diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
      d099e2
      index 3c682659..dcaa41d1 100644
      d099e2
      --- a/src/pcm/pcm_file.c
      d099e2
      +++ b/src/pcm/pcm_file.c
      d099e2
      @@ -579,22 +579,21 @@ static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pc
      d099e2
       {
      d099e2
       	snd_pcm_file_t *file = pcm->private_data;
      d099e2
       	snd_pcm_channel_area_t areas[pcm->channels];
      d099e2
      -	snd_pcm_sframes_t n;
      d099e2
      +	snd_pcm_sframes_t frames;
      d099e2
      +
      d099e2
      +	__snd_pcm_lock(pcm);
      d099e2
      +
      d099e2
      +	frames = _snd_pcm_readi(file->gen.slave, buffer, size);
      d099e2
      +	if (frames <= 0)
      d099e2
      +		return frames;
      d099e2
       
      d099e2
      -	n = _snd_pcm_readi(file->gen.slave, buffer, size);
      d099e2
      -	if (n <= 0)
      d099e2
      -		return n;
      d099e2
      -	if (file->ifd >= 0) {
      d099e2
      -		__snd_pcm_lock(pcm);
      d099e2
      -		n = read(file->ifd, buffer, n * pcm->frame_bits / 8);
      d099e2
      -		__snd_pcm_unlock(pcm);
      d099e2
      -		if (n < 0)
      d099e2
      -			return n;
      d099e2
      -		n = n * 8 / pcm->frame_bits;
      d099e2
      -	}
      d099e2
       	snd_pcm_areas_from_buf(pcm, areas, buffer);
      d099e2
      -	snd_pcm_file_add_frames(pcm, areas, 0, n);
      d099e2
      -	return n;
      d099e2
      +	snd_pcm_file_areas_read_infile(pcm, areas, 0, frames);
      d099e2
      +	snd_pcm_file_add_frames(pcm, areas, 0, frames);
      d099e2
      +
      d099e2
      +	__snd_pcm_unlock(pcm);
      d099e2
      +
      d099e2
      +	return frames;
      d099e2
       }
      d099e2
       
      d099e2
       /* locking */
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 33c7ea0865b7f87cef1c3d3e767734c0edd02e84 Mon Sep 17 00:00:00 2001
      d099e2
      From: Adam Miartus <amiartus@de.adit-jv.com>
      d099e2
      Date: Thu, 23 May 2019 11:44:30 +0200
      d099e2
      Subject: [PATCH 06/25] pcm: file: add missing unlock on early return
      d099e2
      d099e2
      Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
      d099e2
      Signed-off-by: Takashi Iwai <tiwai@suse.de>
      d099e2
      ---
      d099e2
       src/pcm/pcm_file.c | 8 ++++++--
      d099e2
       1 file changed, 6 insertions(+), 2 deletions(-)
      d099e2
      d099e2
      diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
      d099e2
      index dcaa41d1..8e2c70b1 100644
      d099e2
      --- a/src/pcm/pcm_file.c
      d099e2
      +++ b/src/pcm/pcm_file.c
      d099e2
      @@ -584,8 +584,10 @@ static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pc
      d099e2
       	__snd_pcm_lock(pcm);
      d099e2
       
      d099e2
       	frames = _snd_pcm_readi(file->gen.slave, buffer, size);
      d099e2
      -	if (frames <= 0)
      d099e2
      +	if (frames <= 0) {
      d099e2
      +		__snd_pcm_unlock(pcm);
      d099e2
       		return frames;
      d099e2
      +	}
      d099e2
       
      d099e2
       	snd_pcm_areas_from_buf(pcm, areas, buffer);
      d099e2
       	snd_pcm_file_areas_read_infile(pcm, areas, 0, frames);
      d099e2
      @@ -605,8 +607,10 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm
      d099e2
       
      d099e2
       	__snd_pcm_lock(pcm);
      d099e2
       	frames = _snd_pcm_readn(file->gen.slave, bufs, size);
      d099e2
      -	if (frames <= 0)
      d099e2
      +	if (frames <= 0) {
      d099e2
      +		__snd_pcm_unlock(pcm);
      d099e2
       		return frames;
      d099e2
      +	}
      d099e2
       
      d099e2
       	snd_pcm_areas_from_bufs(pcm, areas, bufs);
      d099e2
       	snd_pcm_file_areas_read_infile(pcm, areas, 0, frames);
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 108a2f43791fe769fd58726881b12ad908ebd2e0 Mon Sep 17 00:00:00 2001
      d099e2
      From: Takashi Iwai <tiwai@suse.de>
      d099e2
      Date: Thu, 18 Apr 2019 20:40:18 +0200
      d099e2
      Subject: [PATCH 07/25] ucm: Add UCM profile for CX2072X codec on
      d099e2
       Baytrail/Cherrytrail profiles
      d099e2
      d099e2
      Adding a new Conexant CX2072X codec profile and reusing the existing
      d099e2
      BYT/CHT platform snippets.
      d099e2
      d099e2
      Currently tested only on ASUS E200HA laptop.
      d099e2
      d099e2
      Signed-off-by: Takashi Iwai <tiwai@suse.de>
      d099e2
      ---
      d099e2
       configure.ac                                  |  2 ++
      d099e2
       src/conf/ucm/Makefile.am                      |  1 +
      d099e2
       src/conf/ucm/bytcht-cx2072x/HiFi.conf         | 24 ++++++++++++++++++
      d099e2
       src/conf/ucm/bytcht-cx2072x/Makefile.am       |  4 +++
      d099e2
       .../ucm/bytcht-cx2072x/bytcht-cx2072x.conf    |  8 ++++++
      d099e2
       src/conf/ucm/codecs/Makefile.am               |  1 +
      d099e2
       src/conf/ucm/codecs/cx2072x/DisableSeq.conf   |  7 ++++++
      d099e2
       src/conf/ucm/codecs/cx2072x/EnableSeq.conf    | 13 ++++++++++
      d099e2
       src/conf/ucm/codecs/cx2072x/HeadPhones.conf   | 24 ++++++++++++++++++
      d099e2
       src/conf/ucm/codecs/cx2072x/HeadsetMic.conf   | 25 +++++++++++++++++++
      d099e2
       src/conf/ucm/codecs/cx2072x/InternalMic.conf  | 24 ++++++++++++++++++
      d099e2
       src/conf/ucm/codecs/cx2072x/Makefile.am       |  6 +++++
      d099e2
       src/conf/ucm/codecs/cx2072x/Speaker.conf      | 23 +++++++++++++++++
      d099e2
       13 files changed, 162 insertions(+)
      d099e2
       create mode 100644 src/conf/ucm/bytcht-cx2072x/HiFi.conf
      d099e2
       create mode 100644 src/conf/ucm/bytcht-cx2072x/Makefile.am
      d099e2
       create mode 100644 src/conf/ucm/bytcht-cx2072x/bytcht-cx2072x.conf
      d099e2
       create mode 100644 src/conf/ucm/codecs/cx2072x/DisableSeq.conf
      d099e2
       create mode 100644 src/conf/ucm/codecs/cx2072x/EnableSeq.conf
      d099e2
       create mode 100644 src/conf/ucm/codecs/cx2072x/HeadPhones.conf
      d099e2
       create mode 100644 src/conf/ucm/codecs/cx2072x/HeadsetMic.conf
      d099e2
       create mode 100644 src/conf/ucm/codecs/cx2072x/InternalMic.conf
      d099e2
       create mode 100644 src/conf/ucm/codecs/cx2072x/Makefile.am
      d099e2
       create mode 100644 src/conf/ucm/codecs/cx2072x/Speaker.conf
      d099e2
      d099e2
      diff --git a/configure.ac b/configure.ac
      d099e2
      index 0fb34de4..2e955760 100644
      d099e2
      --- a/configure.ac
      d099e2
      +++ b/configure.ac
      d099e2
      @@ -720,6 +720,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \
      d099e2
       	  src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/Makefile \
      d099e2
       	  src/conf/ucm/broadwell-rt286/Makefile \
      d099e2
       	  src/conf/ucm/broxton-rt298/Makefile \
      d099e2
      +	  src/conf/ucm/bytcht-cx2072x/Makefile \
      d099e2
       	  src/conf/ucm/bytcht-es8316/Makefile \
      d099e2
       	  src/conf/ucm/bytcht-es8316-mono-spk-in1-mic/Makefile \
      d099e2
       	  src/conf/ucm/bytcht-es8316-mono-spk-in2-mic/Makefile \
      d099e2
      @@ -765,6 +766,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \
      d099e2
       	  src/conf/ucm/tegraalc5632/Makefile \
      d099e2
       	  src/conf/ucm/VEYRON-I2S/Makefile \
      d099e2
       	  src/conf/ucm/codecs/Makefile \
      d099e2
      +	  src/conf/ucm/codecs/cx2072x/Makefile \
      d099e2
       	  src/conf/ucm/codecs/es8316/Makefile \
      d099e2
       	  src/conf/ucm/codecs/nau8824/Makefile \
      d099e2
       	  src/conf/ucm/codecs/rt5640/Makefile \
      d099e2
      diff --git a/src/conf/ucm/Makefile.am b/src/conf/ucm/Makefile.am
      d099e2
      index e9f88ed6..02257048 100644
      d099e2
      --- a/src/conf/ucm/Makefile.am
      d099e2
      +++ b/src/conf/ucm/Makefile.am
      d099e2
      @@ -4,6 +4,7 @@ platforms \
      d099e2
       ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN \
      d099e2
       broadwell-rt286 \
      d099e2
       broxton-rt298 \
      d099e2
      +bytcht-cx2072x \
      d099e2
       bytcht-es8316 \
      d099e2
       bytcht-es8316-mono-spk-in1-mic \
      d099e2
       bytcht-es8316-mono-spk-in2-mic \
      d099e2
      diff --git a/src/conf/ucm/bytcht-cx2072x/HiFi.conf b/src/conf/ucm/bytcht-cx2072x/HiFi.conf
      d099e2
      new file mode 100644
      d099e2
      index 00000000..e9c1f757
      d099e2
      --- /dev/null
      d099e2
      +++ b/src/conf/ucm/bytcht-cx2072x/HiFi.conf
      d099e2
      @@ -0,0 +1,24 @@
      d099e2
      +SectionVerb {
      d099e2
      +	EnableSequence [
      d099e2
      +		cdev "hw:bytchtcx2072x"
      d099e2
      +		<platforms/bytcr/PlatformEnableSeq.conf>
      d099e2
      +		<codecs/cx2072x/EnableSeq.conf>
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	DisableSequence [
      d099e2
      +		cdev "hw:bytchtcx2072x"
      d099e2
      +		<codecs/cx2072x/DisableSeq.conf>
      d099e2
      +		<platforms/bytcr/PlatformDisableSeq.conf>
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	Value {
      d099e2
      +		PlaybackPCM "hw:bytchtcx2072x"
      d099e2
      +		CapturePCM "hw:bytchtcx2072x"
      d099e2
      +	}
      d099e2
      +}
      d099e2
      +
      d099e2
      +<codecs/cx2072x/Speaker.conf>
      d099e2
      +<codecs/cx2072x/HeadPhones.conf>
      d099e2
      +
      d099e2
      +<codecs/cx2072x/InternalMic.conf>
      d099e2
      +<codecs/cx2072x/HeadsetMic.conf>
      d099e2
      diff --git a/src/conf/ucm/bytcht-cx2072x/Makefile.am b/src/conf/ucm/bytcht-cx2072x/Makefile.am
      d099e2
      new file mode 100644
      d099e2
      index 00000000..373b2a77
      d099e2
      --- /dev/null
      d099e2
      +++ b/src/conf/ucm/bytcht-cx2072x/Makefile.am
      d099e2
      @@ -0,0 +1,4 @@
      d099e2
      +alsaconfigdir = @ALSA_CONFIG_DIR@
      d099e2
      +ucmdir = $(alsaconfigdir)/ucm/bytcht-cx2072x
      d099e2
      +ucm_DATA = bytcht-cx2072x.conf HiFi.conf
      d099e2
      +EXTRA_DIST = $(ucm_DATA)
      d099e2
      diff --git a/src/conf/ucm/bytcht-cx2072x/bytcht-cx2072x.conf b/src/conf/ucm/bytcht-cx2072x/bytcht-cx2072x.conf
      d099e2
      new file mode 100644
      d099e2
      index 00000000..fce04456
      d099e2
      --- /dev/null
      d099e2
      +++ b/src/conf/ucm/bytcht-cx2072x/bytcht-cx2072x.conf
      d099e2
      @@ -0,0 +1,8 @@
      d099e2
      +SectionUseCase."HiFi" {
      d099e2
      +	File "HiFi.conf"
      d099e2
      +	Comment "Play HiFi quality Music"
      d099e2
      +}
      d099e2
      +
      d099e2
      +SectionDefaults [
      d099e2
      +	cdev "hw:bytchtcx2072x"
      d099e2
      +]
      d099e2
      diff --git a/src/conf/ucm/codecs/Makefile.am b/src/conf/ucm/codecs/Makefile.am
      d099e2
      index f78fd081..5987b9cf 100644
      d099e2
      --- a/src/conf/ucm/codecs/Makefile.am
      d099e2
      +++ b/src/conf/ucm/codecs/Makefile.am
      d099e2
      @@ -1,4 +1,5 @@
      d099e2
       SUBDIRS=\
      d099e2
      +cx2072x \
      d099e2
       es8316 \
      d099e2
       rt5640 \
      d099e2
       rt5645 \
      d099e2
      diff --git a/src/conf/ucm/codecs/cx2072x/DisableSeq.conf b/src/conf/ucm/codecs/cx2072x/DisableSeq.conf
      d099e2
      new file mode 100644
      d099e2
      index 00000000..1e3d5489
      d099e2
      --- /dev/null
      d099e2
      +++ b/src/conf/ucm/codecs/cx2072x/DisableSeq.conf
      d099e2
      @@ -0,0 +1,7 @@
      d099e2
      +# Output Configuration
      d099e2
      +cset "name='I2S DAC1L Switch' off"
      d099e2
      +cset "name='I2S DAC1R Switch' off"
      d099e2
      +
      d099e2
      +# Input Configuration
      d099e2
      +cset "name='I2S ADC1L Switch' off"
      d099e2
      +cset "name='I2S ADC1R Switch' off"
      d099e2
      diff --git a/src/conf/ucm/codecs/cx2072x/EnableSeq.conf b/src/conf/ucm/codecs/cx2072x/EnableSeq.conf
      d099e2
      new file mode 100644
      d099e2
      index 00000000..fb8e3fe2
      d099e2
      --- /dev/null
      d099e2
      +++ b/src/conf/ucm/codecs/cx2072x/EnableSeq.conf
      d099e2
      @@ -0,0 +1,13 @@
      d099e2
      +# Disable all inputs / outputs
      d099e2
      +cset "name='Ext Spk Switch' off"
      d099e2
      +cset "name='Headphone Switch' off"
      d099e2
      +cset "name='Headset Mic Switch' off"
      d099e2
      +cset "name='Int Mic Switch' off"
      d099e2
      +
      d099e2
      +# Output Configuration
      d099e2
      +cset "name='I2S DAC1L Switch' on"
      d099e2
      +cset "name='I2S DAC1R Switch' on"
      d099e2
      +
      d099e2
      +# Input Configuration
      d099e2
      +cset "name='I2S ADC1L Switch' on"
      d099e2
      +cset "name='I2S ADC1R Switch' on"
      d099e2
      diff --git a/src/conf/ucm/codecs/cx2072x/HeadPhones.conf b/src/conf/ucm/codecs/cx2072x/HeadPhones.conf
      d099e2
      new file mode 100644
      d099e2
      index 00000000..4e3ff950
      d099e2
      --- /dev/null
      d099e2
      +++ b/src/conf/ucm/codecs/cx2072x/HeadPhones.conf
      d099e2
      @@ -0,0 +1,24 @@
      d099e2
      +SectionDevice."Headphones" {
      d099e2
      +	Comment "Headphones"
      d099e2
      +
      d099e2
      +	ConflictingDevice [
      d099e2
      +		"Speaker"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	EnableSequence [
      d099e2
      +		cdev "hw:bytchtcx2072x"
      d099e2
      +		cset "name='Headphone Switch' on"
      d099e2
      +		cset "name='PortA Out En Switch' on"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	DisableSequence [
      d099e2
      +		cdev "hw:bytchtcx2072x"
      d099e2
      +		cset "name='Headphone Switch' off"
      d099e2
      +		cset "name='PortA Out En Switch' off"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	Value {
      d099e2
      +		PlaybackChannels "2"
      d099e2
      +		JackControl "Headphone Jack"
      d099e2
      +	}
      d099e2
      +}
      d099e2
      diff --git a/src/conf/ucm/codecs/cx2072x/HeadsetMic.conf b/src/conf/ucm/codecs/cx2072x/HeadsetMic.conf
      d099e2
      new file mode 100644
      d099e2
      index 00000000..26b8df16
      d099e2
      --- /dev/null
      d099e2
      +++ b/src/conf/ucm/codecs/cx2072x/HeadsetMic.conf
      d099e2
      @@ -0,0 +1,25 @@
      d099e2
      +SectionDevice."HeadsetMic" {
      d099e2
      +	Comment "Headset Microphone"
      d099e2
      +
      d099e2
      +	ConflictingDevice [
      d099e2
      +		"InternalMic"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	EnableSequence [
      d099e2
      +		cdev "hw:bytchtcx2072x"
      d099e2
      +		cset "name='Headset Mic Switch' on"
      d099e2
      +		cset "name='ADC1 Mux' 'PortD Switch'"
      d099e2
      +		cset "name='PortD In En Switch' on"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	DisableSequence [
      d099e2
      +		cdev "hw:bytchtcx2072x"
      d099e2
      +		cset "name='Headset Mic Switch' off"
      d099e2
      +		cset "name='PortD In En Switch' off"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	Value {
      d099e2
      +		CaptureChannels "2"
      d099e2
      +		JackControl "Headset Mic Jack"
      d099e2
      +	}
      d099e2
      +}
      d099e2
      diff --git a/src/conf/ucm/codecs/cx2072x/InternalMic.conf b/src/conf/ucm/codecs/cx2072x/InternalMic.conf
      d099e2
      new file mode 100644
      d099e2
      index 00000000..a3e14538
      d099e2
      --- /dev/null
      d099e2
      +++ b/src/conf/ucm/codecs/cx2072x/InternalMic.conf
      d099e2
      @@ -0,0 +1,24 @@
      d099e2
      +SectionDevice."InternalMic" {
      d099e2
      +	Comment "Internal Microphone"
      d099e2
      +
      d099e2
      +	ConflictingDevice [
      d099e2
      +		"HeadsetMic"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	EnableSequence [
      d099e2
      +		cdev "hw:bytchtcx2072x"
      d099e2
      +		cset "name='Int Mic Switch' on"
      d099e2
      +		cset "name='ADC1 Mux' 'PortC Switch'"
      d099e2
      +		cset "name='PortC In En Switch' on"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	DisableSequence [
      d099e2
      +		cdev "hw:bytchtcx2072x"
      d099e2
      +		cset "name='Int Mic Switch' off"
      d099e2
      +		cset "name='PortC In En Switch' off"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	Value {
      d099e2
      +		CaptureChannels "2"
      d099e2
      +	}
      d099e2
      +}
      d099e2
      diff --git a/src/conf/ucm/codecs/cx2072x/Makefile.am b/src/conf/ucm/codecs/cx2072x/Makefile.am
      d099e2
      new file mode 100644
      d099e2
      index 00000000..2990fd09
      d099e2
      --- /dev/null
      d099e2
      +++ b/src/conf/ucm/codecs/cx2072x/Makefile.am
      d099e2
      @@ -0,0 +1,6 @@
      d099e2
      +alsaconfigdir = @ALSA_CONFIG_DIR@
      d099e2
      +ucmdir = $(alsaconfigdir)/ucm/codecs/cx2072x
      d099e2
      +ucm_DATA = EnableSeq.conf DisableSeq.conf \
      d099e2
      +	HeadPhones.conf Speaker.conf \
      d099e2
      +	InternalMic.conf HeadsetMic.conf
      d099e2
      +EXTRA_DIST = $(ucm_DATA)
      d099e2
      diff --git a/src/conf/ucm/codecs/cx2072x/Speaker.conf b/src/conf/ucm/codecs/cx2072x/Speaker.conf
      d099e2
      new file mode 100644
      d099e2
      index 00000000..55e2b2ba
      d099e2
      --- /dev/null
      d099e2
      +++ b/src/conf/ucm/codecs/cx2072x/Speaker.conf
      d099e2
      @@ -0,0 +1,23 @@
      d099e2
      +SectionDevice."Speaker" {
      d099e2
      +	Comment "Speakers"
      d099e2
      +
      d099e2
      +	ConflictingDevice [
      d099e2
      +		"Headphones"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	EnableSequence [
      d099e2
      +		cdev "hw:bytchtcx2072x"
      d099e2
      +		cset "name='Ext Spk Switch' on"
      d099e2
      +		cset "name='PortG Out En Switch' on"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	DisableSequence [
      d099e2
      +		cdev "hw:bytchtcx2072x"
      d099e2
      +		cset "name='Ext Spk Switch' off"
      d099e2
      +		cset "name='PortG Out En Switch' off"
      d099e2
      +	]
      d099e2
      +
      d099e2
      +	Value {
      d099e2
      +		PlaybackChannels "2"
      d099e2
      +	}
      d099e2
      +}
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From e520f454803acfdb9af5cd7224129b37904eef4a Mon Sep 17 00:00:00 2001
      d099e2
      From: Adam Miartus <amiartus@de.adit-jv.com>
      d099e2
      Date: Thu, 23 May 2019 15:00:39 +0200
      d099e2
      Subject: [PATCH 08/25] pcm: add mmap_begin callback to snd_pcm_fast_ops_t api
      d099e2
      d099e2
      main motivation for adding the callback is to use it to enable operation
      d099e2
      on mmaped buffer before user access for pcm_file plugin
      d099e2
      d099e2
      support for MMAP read access with masking by data from input file is not
      d099e2
      implemented for pcm_file plugin, by adding this callback implementing
      d099e2
      such feature can be done by rewriting next continuous portion of buffer
      d099e2
      on each mmap_begin call
      d099e2
      d099e2
      plugins like softvol use pcm_plugin interface and overwrite the buffer by
      d099e2
      looping around it in avail_update callback, this patch hopes to simplify
      d099e2
      the task by adding new api callback, removing the need for rewriting
      d099e2
      pcm_file (to use pcm_plugin callbacks) and careful checking when looping
      d099e2
      around whole mmaped buffer
      d099e2
      d099e2
      Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
      d099e2
      Reviewed-by: Timo Wischer <twischer@de.adit-jv.com>
      d099e2
      Signed-off-by: Takashi Iwai <tiwai@suse.de>
      d099e2
      ---
      d099e2
       src/pcm/pcm.c       | 6 ++++++
      d099e2
       src/pcm/pcm_local.h | 1 +
      d099e2
       2 files changed, 7 insertions(+)
      d099e2
      d099e2
      diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
      d099e2
      index 3a71d79b..323926e1 100644
      d099e2
      --- a/src/pcm/pcm.c
      d099e2
      +++ b/src/pcm/pcm.c
      d099e2
      @@ -7129,7 +7129,13 @@ int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
      d099e2
       	snd_pcm_uframes_t f;
      d099e2
       	snd_pcm_uframes_t avail;
      d099e2
       	const snd_pcm_channel_area_t *xareas;
      d099e2
      +
      d099e2
       	assert(pcm && areas && offset && frames);
      d099e2
      +
      d099e2
      +	if (pcm->fast_ops->mmap_begin)
      d099e2
      +		return pcm->fast_ops->mmap_begin(pcm->fast_op_arg, areas, offset, frames);
      d099e2
      +
      d099e2
      +	/* fallback for plugins that do not specify new callback */
      d099e2
       	xareas = snd_pcm_mmap_areas(pcm);
      d099e2
       	if (xareas == NULL)
      d099e2
       		return -EBADFD;
      d099e2
      diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
      d099e2
      index d52229d8..d5726eb2 100644
      d099e2
      --- a/src/pcm/pcm_local.h
      d099e2
      +++ b/src/pcm/pcm_local.h
      d099e2
      @@ -184,6 +184,7 @@ typedef struct {
      d099e2
       	int (*poll_descriptors)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space); /* locked */
      d099e2
       	int (*poll_revents)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); /* locked */
      d099e2
       	int (*may_wait_for_avail_min)(snd_pcm_t *pcm, snd_pcm_uframes_t avail);
      d099e2
      +	int (*mmap_begin)(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames); /* locked */
      d099e2
       } snd_pcm_fast_ops_t;
      d099e2
       
      d099e2
       struct _snd_pcm {
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From fe7ff721a954c3f8c2183febc7c3fa5736357b67 Mon Sep 17 00:00:00 2001
      d099e2
      From: Adam Miartus <amiartus@de.adit-jv.com>
      d099e2
      Date: Thu, 23 May 2019 15:00:40 +0200
      d099e2
      Subject: [PATCH 09/25] pcm: file: add infile read support for mmap mode
      d099e2
      d099e2
      mmap_begin callback is used to copy data from input file to mmaped
      d099e2
      buffer
      d099e2
      d099e2
      guard for corner use of api (multiple mmap_begin calls by user) is
      d099e2
      introduced to check if next continuous buffer was already overwritten
      d099e2
      d099e2
      buffer is overwritten with input file data only in case of stream capture
      d099e2
      d099e2
      Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
      d099e2
      Reviewed-by: Timo Wischer <twischer@de.adit-jv.com>
      d099e2
      Signed-off-by: Takashi Iwai <tiwai@suse.de>
      d099e2
      ---
      d099e2
       src/pcm/pcm_file.c | 31 +++++++++++++++++++++++++++++++
      d099e2
       1 file changed, 31 insertions(+)
      d099e2
      d099e2
      diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
      d099e2
      index 8e2c70b1..52cc10a9 100644
      d099e2
      --- a/src/pcm/pcm_file.c
      d099e2
      +++ b/src/pcm/pcm_file.c
      d099e2
      @@ -88,6 +88,7 @@ typedef struct {
      d099e2
       	size_t buffer_bytes;
      d099e2
       	struct wav_fmt wav_header;
      d099e2
       	size_t filelen;
      d099e2
      +	char ifmmap_overwritten;
      d099e2
       } snd_pcm_file_t;
      d099e2
       
      d099e2
       #if __BYTE_ORDER == __LITTLE_ENDIAN
      d099e2
      @@ -630,6 +631,8 @@ static snd_pcm_sframes_t snd_pcm_file_mmap_commit(snd_pcm_t *pcm,
      d099e2
       	const snd_pcm_channel_area_t *areas;
      d099e2
       	snd_pcm_sframes_t result;
      d099e2
       
      d099e2
      +	file->ifmmap_overwritten = 0;
      d099e2
      +
      d099e2
       	result = snd_pcm_mmap_begin(file->gen.slave, &areas, &ofs, &siz;;
      d099e2
       	if (result >= 0) {
      d099e2
       		assert(ofs == offset && siz == size);
      d099e2
      @@ -640,6 +643,32 @@ static snd_pcm_sframes_t snd_pcm_file_mmap_commit(snd_pcm_t *pcm,
      d099e2
       	return result;
      d099e2
       }
      d099e2
       
      d099e2
      +static int snd_pcm_file_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
      d099e2
      +	snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
      d099e2
      +{
      d099e2
      +	snd_pcm_file_t *file = pcm->private_data;
      d099e2
      +	snd_pcm_channel_area_t areas_if[pcm->channels];
      d099e2
      +	snd_pcm_uframes_t frames_if;
      d099e2
      +	void *buffer = NULL;
      d099e2
      +	int result;
      d099e2
      +
      d099e2
      +	result = snd_pcm_mmap_begin(file->gen.slave, areas, offset, frames);
      d099e2
      +	if (result < 0)
      d099e2
      +		return result;
      d099e2
      +
      d099e2
      +	if (pcm->stream != SND_PCM_STREAM_CAPTURE)
      d099e2
      +		return result;
      d099e2
      +
      d099e2
      +	/* user may run mmap_begin without mmap_commit multiple times in row */
      d099e2
      +	if (file->ifmmap_overwritten)
      d099e2
      +		return result;
      d099e2
      +	file->ifmmap_overwritten = 1;
      d099e2
      +
      d099e2
      +	snd_pcm_file_areas_read_infile(pcm, *areas, *offset, *frames);
      d099e2
      +
      d099e2
      +	return result;
      d099e2
      +}
      d099e2
      +
      d099e2
       static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
      d099e2
       {
      d099e2
       	snd_pcm_file_t *file = pcm->private_data;
      d099e2
      @@ -666,6 +695,7 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
      d099e2
       	file->wbuf_size = slave->buffer_size * 2;
      d099e2
       	file->wbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->wbuf_size);
      d099e2
       	file->wbuf_used_bytes = 0;
      d099e2
      +	file->ifmmap_overwritten = 0;
      d099e2
       	assert(!file->wbuf);
      d099e2
       	file->wbuf = malloc(file->wbuf_size_bytes);
      d099e2
       	if (file->wbuf == NULL) {
      d099e2
      @@ -777,6 +807,7 @@ static const snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
      d099e2
       	.poll_descriptors = snd_pcm_generic_poll_descriptors,
      d099e2
       	.poll_revents = snd_pcm_generic_poll_revents,
      d099e2
       	.htimestamp = snd_pcm_generic_htimestamp,
      d099e2
      +	.mmap_begin = snd_pcm_file_mmap_begin,
      d099e2
       };
      d099e2
       
      d099e2
       /**
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 47bc6d534102aca9cc2aed1b6bdd5633ef645a3f Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 10:27:25 +0200
      d099e2
      Subject: [PATCH 10/25] aserver: fix resource leak coverity
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       aserver/aserver.c | 33 +++++++++++++++++++--------------
      d099e2
       1 file changed, 19 insertions(+), 14 deletions(-)
      d099e2
      d099e2
      diff --git a/aserver/aserver.c b/aserver/aserver.c
      d099e2
      index 066414d8..6d20f330 100644
      d099e2
      --- a/aserver/aserver.c
      d099e2
      +++ b/aserver/aserver.c
      d099e2
      @@ -75,6 +75,7 @@ static int make_local_socket(const char *filename)
      d099e2
       	if (bind(sock, (struct sockaddr *) addr, size) < 0) {
      d099e2
       		int result = -errno;
      d099e2
       		SYSERROR("bind failed");
      d099e2
      +		close(sock);
      d099e2
       		return result;
      d099e2
       	}
      d099e2
       
      d099e2
      @@ -101,6 +102,7 @@ static int make_inet_socket(int port)
      d099e2
       	if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
      d099e2
       		int result = -errno;
      d099e2
       		SYSERROR("bind failed");
      d099e2
      +		close(sock);
      d099e2
       		return result;
      d099e2
       	}
      d099e2
       
      d099e2
      @@ -916,10 +918,9 @@ static int inet_handler(waiter_t *waiter, unsigned short events ATTRIBUTE_UNUSED
      d099e2
       
      d099e2
       static int server(const char *sockname, int port)
      d099e2
       {
      d099e2
      -	int err;
      d099e2
      +	int err, result, sockn = -1, socki = -1;
      d099e2
       	unsigned int k;
      d099e2
       	long open_max;
      d099e2
      -	int result;
      d099e2
       
      d099e2
       	if (!sockname && port < 0)
      d099e2
       		return -EINVAL;
      d099e2
      @@ -933,36 +934,36 @@ static int server(const char *sockname, int port)
      d099e2
       	waiters = calloc((size_t) open_max, sizeof(*waiters));
      d099e2
       
      d099e2
       	if (sockname) {
      d099e2
      -		int sock = make_local_socket(sockname);
      d099e2
      -		if (sock < 0)
      d099e2
      -			return sock;
      d099e2
      -		if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
      d099e2
      +		sockn = make_local_socket(sockname);
      d099e2
      +		if (sockn < 0)
      d099e2
      +			return sockn;
      d099e2
      +		if (fcntl(sockn, F_SETFL, O_NONBLOCK) < 0) {
      d099e2
       			result = -errno;
      d099e2
       			SYSERROR("fcntl O_NONBLOCK failed");
      d099e2
       			goto _end;
      d099e2
       		}
      d099e2
      -		if (listen(sock, 4) < 0) {
      d099e2
      +		if (listen(sockn, 4) < 0) {
      d099e2
       			result = -errno;
      d099e2
       			SYSERROR("listen failed");
      d099e2
       			goto _end;
      d099e2
       		}
      d099e2
      -		add_waiter(sock, POLLIN, local_handler, NULL);
      d099e2
      +		add_waiter(sockn, POLLIN, local_handler, NULL);
      d099e2
       	}
      d099e2
       	if (port >= 0) {
      d099e2
      -		int sock = make_inet_socket(port);
      d099e2
      -		if (sock < 0)
      d099e2
      -			return sock;
      d099e2
      -		if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
      d099e2
      +		socki = make_inet_socket(port);
      d099e2
      +		if (socki < 0)
      d099e2
      +			return socki;
      d099e2
      +		if (fcntl(socki, F_SETFL, O_NONBLOCK) < 0) {
      d099e2
       			result = -errno;
      d099e2
       			SYSERROR("fcntl failed");
      d099e2
       			goto _end;
      d099e2
       		}
      d099e2
      -		if (listen(sock, 4) < 0) {
      d099e2
      +		if (listen(socki, 4) < 0) {
      d099e2
       			result = -errno;
      d099e2
       			SYSERROR("listen failed");
      d099e2
       			goto _end;
      d099e2
       		}
      d099e2
      -		add_waiter(sock, POLLIN, inet_handler, NULL);
      d099e2
      +		add_waiter(socki, POLLIN, inet_handler, NULL);
      d099e2
       	}
      d099e2
       
      d099e2
       	while (1) {
      d099e2
      @@ -991,6 +992,10 @@ static int server(const char *sockname, int port)
      d099e2
       		}
      d099e2
       	}
      d099e2
        _end:
      d099e2
      +	if (sockn >= 0)
      d099e2
      +		close(sockn);
      d099e2
      +	if (socki >= 0)
      d099e2
      +		close(socki);
      d099e2
       	free(pollfds);
      d099e2
       	free(waiters);
      d099e2
       	return result;
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 4aa960c48b4d292425597d283f3ef15d02590082 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 10:39:05 +0200
      d099e2
      Subject: [PATCH 11/25] src/conf.c: add missing va_end() call (coverity)
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/conf.c | 8 ++++++--
      d099e2
       1 file changed, 6 insertions(+), 2 deletions(-)
      d099e2
      d099e2
      diff --git a/src/conf.c b/src/conf.c
      d099e2
      index cda5518e..3a3c91bf 100644
      d099e2
      --- a/src/conf.c
      d099e2
      +++ b/src/conf.c
      d099e2
      @@ -3034,8 +3034,10 @@ int snd_config_save(snd_config_t *config, snd_output_t *out)
      d099e2
       		if (!k) \
      d099e2
       			break; \
      d099e2
       		err = fcn(config, k, &n); \
      d099e2
      -		if (err < 0) \
      d099e2
      +		if (err < 0) { \
      d099e2
      +			va_end(arg); \
      d099e2
       			return err; \
      d099e2
      +		} \
      d099e2
       		config = n; \
      d099e2
       	} \
      d099e2
       	va_end(arg); \
      d099e2
      @@ -3056,8 +3058,10 @@ int snd_config_save(snd_config_t *config, snd_output_t *out)
      d099e2
       		if (!k) \
      d099e2
       			break; \
      d099e2
       		err = fcn(root, config, k, &n); \
      d099e2
      -		if (err < 0) \
      d099e2
      +		if (err < 0) { \
      d099e2
      +			va_end(arg); \
      d099e2
       			return err; \
      d099e2
      +		} \
      d099e2
       		config = n; \
      d099e2
       	} \
      d099e2
       	va_end(arg); \
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 990b1a53ed800caac0bab1c2b7987205569861fe Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 10:44:49 +0200
      d099e2
      Subject: [PATCH 12/25] config: parse_string() fix the dynamic buffer
      d099e2
       allocation failure code (coverity)
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/conf.c | 16 ++++++++++++----
      d099e2
       1 file changed, 12 insertions(+), 4 deletions(-)
      d099e2
      d099e2
      diff --git a/src/conf.c b/src/conf.c
      d099e2
      index 3a3c91bf..3e4b76a3 100644
      d099e2
      --- a/src/conf.c
      d099e2
      +++ b/src/conf.c
      d099e2
      @@ -4747,8 +4747,11 @@ static int parse_string(const char **ptr, char **val)
      d099e2
       			return -EINVAL;
      d099e2
       		case '\\':
      d099e2
       			c = parse_char(ptr);
      d099e2
      -			if (c < 0)
      d099e2
      +			if (c < 0) {
      d099e2
      +				if (alloc > bufsize)
      d099e2
      +					free(buf);
      d099e2
       				return c;
      d099e2
      +			}
      d099e2
       			break;
      d099e2
       		default:
      d099e2
       			(*ptr)++;
      d099e2
      @@ -4768,12 +4771,17 @@ static int parse_string(const char **ptr, char **val)
      d099e2
       			alloc *= 2;
      d099e2
       			if (old_alloc == bufsize) {
      d099e2
       				buf = malloc(alloc);
      d099e2
      +				if (!buf)
      d099e2
      +					return -ENOMEM;
      d099e2
       				memcpy(buf, _buf, old_alloc);
      d099e2
       			} else {
      d099e2
      -				buf = realloc(buf, alloc);
      d099e2
      +				char *buf2 = realloc(buf, alloc);
      d099e2
      +				if (!buf2) {
      d099e2
      +					free(buf);
      d099e2
      +					return -ENOMEM;
      d099e2
      +				}
      d099e2
      +				buf = buf2;
      d099e2
       			}
      d099e2
      -			if (!buf)
      d099e2
      -				return -ENOMEM;
      d099e2
       		}
      d099e2
       		buf[idx++] = c;
      d099e2
       	}
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 51881cacc05e7d5e3cc8fc1ec9a4ac93a6327703 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 10:51:47 +0200
      d099e2
      Subject: [PATCH 13/25] control_shm: remove duplicate code (coverity)
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/control/control_shm.c | 18 +++---------------
      d099e2
       1 file changed, 3 insertions(+), 15 deletions(-)
      d099e2
      d099e2
      diff --git a/src/control/control_shm.c b/src/control/control_shm.c
      d099e2
      index d7b41398..1d9de8b7 100644
      d099e2
      --- a/src/control/control_shm.c
      d099e2
      +++ b/src/control/control_shm.c
      d099e2
      @@ -302,13 +302,9 @@ static int snd_ctl_shm_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev)
      d099e2
       {
      d099e2
       	snd_ctl_shm_t *shm = ctl->private_data;
      d099e2
       	volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
      d099e2
      -	int err;
      d099e2
       	ctrl->u.pcm_prefer_subdevice = subdev;
      d099e2
       	ctrl->cmd = SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE;
      d099e2
      -	err = snd_ctl_shm_action(ctl);
      d099e2
      -	if (err < 0)
      d099e2
      -		return err;
      d099e2
      -	return err;
      d099e2
      +	return snd_ctl_shm_action(ctl);
      d099e2
       }
      d099e2
       
      d099e2
       static int snd_ctl_shm_rawmidi_next_device(snd_ctl_t *ctl, int * device)
      d099e2
      @@ -343,26 +339,18 @@ static int snd_ctl_shm_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev)
      d099e2
       {
      d099e2
       	snd_ctl_shm_t *shm = ctl->private_data;
      d099e2
       	volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
      d099e2
      -	int err;
      d099e2
       	ctrl->u.rawmidi_prefer_subdevice = subdev;
      d099e2
       	ctrl->cmd = SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE;
      d099e2
      -	err = snd_ctl_shm_action(ctl);
      d099e2
      -	if (err < 0)
      d099e2
      -		return err;
      d099e2
      -	return err;
      d099e2
      +	return snd_ctl_shm_action(ctl);
      d099e2
       }
      d099e2
       
      d099e2
       static int snd_ctl_shm_set_power_state(snd_ctl_t *ctl, unsigned int state)
      d099e2
       {
      d099e2
       	snd_ctl_shm_t *shm = ctl->private_data;
      d099e2
       	volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
      d099e2
      -	int err;
      d099e2
       	ctrl->u.power_state = state;
      d099e2
       	ctrl->cmd = SNDRV_CTL_IOCTL_POWER;
      d099e2
      -	err = snd_ctl_shm_action(ctl);
      d099e2
      -	if (err < 0)
      d099e2
      -		return err;
      d099e2
      -	return err;
      d099e2
      +	return snd_ctl_shm_action(ctl);
      d099e2
       }
      d099e2
       
      d099e2
       static int snd_ctl_shm_get_power_state(snd_ctl_t *ctl, unsigned int *state)
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From d6ba264038fde08baf5e62bdde2a5614792db5c8 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 10:53:09 +0200
      d099e2
      Subject: [PATCH 14/25] control_shm: add missing socket close to the error path
      d099e2
       (coverity)
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/control/control_shm.c | 4 +++-
      d099e2
       1 file changed, 3 insertions(+), 1 deletion(-)
      d099e2
      d099e2
      diff --git a/src/control/control_shm.c b/src/control/control_shm.c
      d099e2
      index 1d9de8b7..40d42643 100644
      d099e2
      --- a/src/control/control_shm.c
      d099e2
      +++ b/src/control/control_shm.c
      d099e2
      @@ -424,8 +424,10 @@ static int make_local_socket(const char *filename)
      d099e2
       	addr->sun_family = AF_LOCAL;
      d099e2
       	memcpy(addr->sun_path, filename, l);
      d099e2
       
      d099e2
      -	if (connect(sock, (struct sockaddr *) addr, size) < 0)
      d099e2
      +	if (connect(sock, (struct sockaddr *) addr, size) < 0) {
      d099e2
      +		close(sock);
      d099e2
       		return -errno;
      d099e2
      +	}
      d099e2
       	return sock;
      d099e2
       }
      d099e2
       
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From d5a1cf35b710d255508e56ed19633e1fbf41a2d4 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 10:57:20 +0200
      d099e2
      Subject: [PATCH 15/25] pcm: fix memory leak in _snd_pcm_parse_config_chmaps()
      d099e2
       (coverity)
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/pcm/pcm.c | 1 +
      d099e2
       1 file changed, 1 insertion(+)
      d099e2
      d099e2
      diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
      d099e2
      index 323926e1..fa51ca99 100644
      d099e2
      --- a/src/pcm/pcm.c
      d099e2
      +++ b/src/pcm/pcm.c
      d099e2
      @@ -8391,6 +8391,7 @@ _snd_pcm_parse_config_chmaps(snd_config_t *conf)
      d099e2
       			free(chmap);
      d099e2
       			goto error;
      d099e2
       		}
      d099e2
      +		free(chmap);
      d099e2
       		nums++;
      d099e2
       	}
      d099e2
       	return maps;
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 22ade9b8c150240a960ca683ee6d8f53ce8bc6ea Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 11:09:43 +0200
      d099e2
      Subject: [PATCH 16/25] pcm_file: call pclose() correctly for popen()
      d099e2
       (coverity)
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/pcm/pcm_file.c | 9 ++++++++-
      d099e2
       1 file changed, 8 insertions(+), 1 deletion(-)
      d099e2
      d099e2
      diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
      d099e2
      index 52cc10a9..99db3754 100644
      d099e2
      --- a/src/pcm/pcm_file.c
      d099e2
      +++ b/src/pcm/pcm_file.c
      d099e2
      @@ -227,7 +227,14 @@ static int snd_pcm_file_open_output_file(snd_pcm_file_t *file)
      d099e2
       					file->final_fname);
      d099e2
       			return -errno;
      d099e2
       		}
      d099e2
      -		fd = fileno(pipe);
      d099e2
      +		fd = dup(fileno(pipe));
      d099e2
      +		err = -errno;
      d099e2
      +		pclose(pipe);
      d099e2
      +		if (fd < 0) {
      d099e2
      +			SYSERR("unable to dup pipe file handle for command %s",
      d099e2
      +					file->final_fname);
      d099e2
      +			return err;
      d099e2
      +		}
      d099e2
       	} else {
      d099e2
       		if (file->trunc)
      d099e2
       			fd = open(file->final_fname, O_WRONLY|O_CREAT|O_TRUNC,
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 3ae743efea704c16c9464f38d502c23759b71245 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 11:11:46 +0200
      d099e2
      Subject: [PATCH 17/25] pcm_hw: close file descriptor in the error path in
      d099e2
       snd_pcm_hw_open() (coverity)
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/pcm/pcm_hw.c | 3 +++
      d099e2
       1 file changed, 3 insertions(+)
      d099e2
      d099e2
      diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
      d099e2
      index 91370a88..77d4dae1 100644
      d099e2
      --- a/src/pcm/pcm_hw.c
      d099e2
      +++ b/src/pcm/pcm_hw.c
      d099e2
      @@ -1724,12 +1724,15 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
      d099e2
       		}
      d099e2
       		if (info.subdevice != (unsigned int) subdevice) {
      d099e2
       			close(fd);
      d099e2
      +			fd = -1;
      d099e2
       			goto __again;
      d099e2
       		}
      d099e2
       	}
      d099e2
       	snd_ctl_close(ctl);
      d099e2
       	return snd_pcm_hw_open_fd(pcmp, name, fd, sync_ptr_ioctl);
      d099e2
              _err:
      d099e2
      +	if (fd >= 0)
      d099e2
      +		close(fd);
      d099e2
       	snd_ctl_close(ctl);
      d099e2
       	return ret;
      d099e2
       }
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 8ab0393b42e08655a5fee0a8e84b3ba84932465b Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 20:31:24 +0200
      d099e2
      Subject: [PATCH 18/25] rawmidi: use snd_dlobj_cache_get2() in rawmidi open
      d099e2
       (coverity)
      d099e2
      d099e2
      Use proper reference counting for the dynamic symbol.
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       include/local.h             |  3 +++
      d099e2
       src/dlmisc.c                | 41 +++++++++++++++++++++++++++++------
      d099e2
       src/rawmidi/rawmidi.c       | 43 ++++++++++++++++---------------------
      d099e2
       src/rawmidi/rawmidi_local.h |  2 +-
      d099e2
       4 files changed, 57 insertions(+), 32 deletions(-)
      d099e2
      d099e2
      diff --git a/include/local.h b/include/local.h
      d099e2
      index 5edad317..e8390df5 100644
      d099e2
      --- a/include/local.h
      d099e2
      +++ b/include/local.h
      d099e2
      @@ -328,6 +328,8 @@ static inline int snd_open_device(const char *filename, int fmode)
      d099e2
       /* make local functions really local */
      d099e2
       #define snd_dlobj_cache_get \
      d099e2
       	snd1_dlobj_cache_get
      d099e2
      +#define snd_dlobj_cache_get2 \
      d099e2
      +	snd1_dlobj_cache_get2
      d099e2
       #define snd_dlobj_cache_put \
      d099e2
       	snd1_dlobj_cache_put
      d099e2
       #define snd_dlobj_cache_cleanup \
      d099e2
      @@ -341,6 +343,7 @@ static inline int snd_open_device(const char *filename, int fmode)
      d099e2
       
      d099e2
       /* dlobj cache */
      d099e2
       void *snd_dlobj_cache_get(const char *lib, const char *name, const char *version, int verbose);
      d099e2
      +void *snd_dlobj_cache_get2(const char *lib, const char *name, const char *version, int verbose);
      d099e2
       int snd_dlobj_cache_put(void *open_func);
      d099e2
       void snd_dlobj_cache_cleanup(void);
      d099e2
       
      d099e2
      diff --git a/src/dlmisc.c b/src/dlmisc.c
      d099e2
      index 012e61bc..8c8f3ff7 100644
      d099e2
      --- a/src/dlmisc.c
      d099e2
      +++ b/src/dlmisc.c
      d099e2
      @@ -251,15 +251,15 @@ static inline void snd_dlobj_unlock(void) {}
      d099e2
       
      d099e2
       static LIST_HEAD(pcm_dlobj_list);
      d099e2
       
      d099e2
      -void *snd_dlobj_cache_get(const char *lib, const char *name,
      d099e2
      -			  const char *version, int verbose)
      d099e2
      +static struct dlobj_cache *
      d099e2
      +snd_dlobj_cache_get0(const char *lib, const char *name,
      d099e2
      +		     const char *version, int verbose)
      d099e2
       {
      d099e2
       	struct list_head *p;
      d099e2
       	struct dlobj_cache *c;
      d099e2
       	void *func, *dlobj;
      d099e2
       	char errbuf[256];
      d099e2
       
      d099e2
      -	snd_dlobj_lock();
      d099e2
       	list_for_each(p, &pcm_dlobj_list) {
      d099e2
       		c = list_entry(p, struct dlobj_cache, list);
      d099e2
       		if (c->lib && lib && strcmp(c->lib, lib) != 0)
      d099e2
      @@ -270,9 +270,7 @@ void *snd_dlobj_cache_get(const char *lib, const char *name,
      d099e2
       			continue;
      d099e2
       		if (strcmp(c->name, name) == 0) {
      d099e2
       			c->refcnt++;
      d099e2
      -			func = c->func;
      d099e2
      -			snd_dlobj_unlock();
      d099e2
      -			return func;
      d099e2
      +			return c;
      d099e2
       		}
      d099e2
       	}
      d099e2
       
      d099e2
      @@ -285,7 +283,6 @@ void *snd_dlobj_cache_get(const char *lib, const char *name,
      d099e2
       			SNDERR("Cannot open shared library %s (%s)",
      d099e2
       						lib ? lib : "[builtin]",
      d099e2
       						errbuf);
      d099e2
      -		snd_dlobj_unlock();
      d099e2
       		return NULL;
      d099e2
       	}
      d099e2
       
      d099e2
      @@ -314,6 +311,36 @@ void *snd_dlobj_cache_get(const char *lib, const char *name,
      d099e2
       	c->dlobj = dlobj;
      d099e2
       	c->func = func;
      d099e2
       	list_add_tail(&c->list, &pcm_dlobj_list);
      d099e2
      +	return c;
      d099e2
      +}
      d099e2
      +
      d099e2
      +void *snd_dlobj_cache_get(const char *lib, const char *name,
      d099e2
      +			  const char *version, int verbose)
      d099e2
      +{
      d099e2
      +	struct dlobj_cache *c;
      d099e2
      +	void *func = NULL;
      d099e2
      +
      d099e2
      +	snd_dlobj_lock();
      d099e2
      +	c = snd_dlobj_cache_get0(lib, name, version, verbose);
      d099e2
      +	if (c)
      d099e2
      +		func = c->func;
      d099e2
      +	snd_dlobj_unlock();
      d099e2
      +	return func;
      d099e2
      +}
      d099e2
      +
      d099e2
      +void *snd_dlobj_cache_get2(const char *lib, const char *name,
      d099e2
      +			   const char *version, int verbose)
      d099e2
      +{
      d099e2
      +	struct dlobj_cache *c;
      d099e2
      +	void *func = NULL;
      d099e2
      +
      d099e2
      +	snd_dlobj_lock();
      d099e2
      +	c = snd_dlobj_cache_get0(lib, name, version, verbose);
      d099e2
      +	if (c) {
      d099e2
      +		func = c->func;
      d099e2
      +		/* double reference */
      d099e2
      +		c->refcnt++;
      d099e2
      +	}
      d099e2
       	snd_dlobj_unlock();
      d099e2
       	return func;
      d099e2
       }
      d099e2
      diff --git a/src/rawmidi/rawmidi.c b/src/rawmidi/rawmidi.c
      d099e2
      index 2f419142..1b5f8525 100644
      d099e2
      --- a/src/rawmidi/rawmidi.c
      d099e2
      +++ b/src/rawmidi/rawmidi.c
      d099e2
      @@ -162,7 +162,7 @@ static int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp
      d099e2
       				 snd_config_t *rawmidi_conf, int mode)
      d099e2
       {
      d099e2
       	const char *str;
      d099e2
      -	char buf[256], errbuf[256];
      d099e2
      +	char buf[256];
      d099e2
       	int err;
      d099e2
       	snd_config_t *conf, *type_conf = NULL;
      d099e2
       	snd_config_iterator_t i, next;
      d099e2
      @@ -174,7 +174,6 @@ static int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp
      d099e2
       #ifndef PIC
      d099e2
       	extern void *snd_rawmidi_open_symbols(void);
      d099e2
       #endif
      d099e2
      -	void *h = NULL;
      d099e2
       	if (snd_config_get_type(rawmidi_conf) != SND_CONFIG_TYPE_COMPOUND) {
      d099e2
       		if (name)
      d099e2
       			SNDERR("Invalid type for RAWMIDI %s definition", name);
      d099e2
      @@ -239,41 +238,37 @@ static int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp
      d099e2
       #ifndef PIC
      d099e2
       	snd_rawmidi_open_symbols();
      d099e2
       #endif
      d099e2
      -	h = INTERNAL(snd_dlopen)(lib, RTLD_NOW, errbuf, sizeof(errbuf));
      d099e2
      -	if (h)
      d099e2
      -		open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_RAWMIDI_DLSYM_VERSION));
      d099e2
      -	err = 0;
      d099e2
      -	if (!h) {
      d099e2
      -		SNDERR("Cannot open shared library %s (%s)", lib, errbuf);
      d099e2
      -		err = -ENOENT;
      d099e2
      -	} else if (!open_func) {
      d099e2
      -		SNDERR("symbol %s is not defined inside %s", open_name, lib);
      d099e2
      -		snd_dlclose(h);
      d099e2
      +	open_func = snd_dlobj_cache_get2(lib, open_name,
      d099e2
      +			SND_DLSYM_VERSION(SND_RAWMIDI_DLSYM_VERSION), 1);
      d099e2
      +	if (!open_func) {
      d099e2
       		err = -ENXIO;
      d099e2
      +		goto _err;
      d099e2
       	}
      d099e2
      -       _err:
      d099e2
       	if (type_conf)
      d099e2
       		snd_config_delete(type_conf);
      d099e2
      -	if (err >= 0)
      d099e2
      -		err = open_func(inputp, outputp, name, rawmidi_root, rawmidi_conf, mode);
      d099e2
      -	if (err < 0) {
      d099e2
      -		if (h)
      d099e2
      -			snd_dlclose(h);
      d099e2
      -		return err;
      d099e2
      -	}
      d099e2
      +	err = open_func(inputp, outputp, name, rawmidi_root, rawmidi_conf, mode);
      d099e2
      +	if (err < 0)
      d099e2
      +		goto _err;
      d099e2
       	if (inputp) {
      d099e2
      -		(*inputp)->dl_handle = h; h = NULL;
      d099e2
      +		(*inputp)->open_func = open_func;
      d099e2
       		snd_rawmidi_params_default(*inputp, &params);
      d099e2
       		err = snd_rawmidi_params(*inputp, &params);
      d099e2
       		assert(err >= 0);
      d099e2
       	}
      d099e2
       	if (outputp) {
      d099e2
      -		(*outputp)->dl_handle = h;
      d099e2
      +		(*outputp)->open_func = open_func;
      d099e2
       		snd_rawmidi_params_default(*outputp, &params);
      d099e2
       		err = snd_rawmidi_params(*outputp, &params);
      d099e2
       		assert(err >= 0);
      d099e2
       	}
      d099e2
       	return 0;
      d099e2
      +
      d099e2
      +       _err:
      d099e2
      +	if (open_func)
      d099e2
      +		snd_dlobj_cache_put(open_func);
      d099e2
      +	if (type_conf)
      d099e2
      +		snd_config_delete(type_conf);
      d099e2
      +	return err;
      d099e2
       }
      d099e2
       
      d099e2
       static int snd_rawmidi_open_noupdate(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
      d099e2
      @@ -350,8 +345,8 @@ int snd_rawmidi_close(snd_rawmidi_t *rawmidi)
      d099e2
         	assert(rawmidi);
      d099e2
       	err = rawmidi->ops->close(rawmidi);
      d099e2
       	free(rawmidi->name);
      d099e2
      -	if (rawmidi->dl_handle)
      d099e2
      -		snd_dlclose(rawmidi->dl_handle);
      d099e2
      +	if (rawmidi->open_func)
      d099e2
      +		snd_dlobj_cache_put(rawmidi->open_func);
      d099e2
       	free(rawmidi);
      d099e2
       	return err;
      d099e2
       }
      d099e2
      diff --git a/src/rawmidi/rawmidi_local.h b/src/rawmidi/rawmidi_local.h
      d099e2
      index d76b35a3..721e1ec9 100644
      d099e2
      --- a/src/rawmidi/rawmidi_local.h
      d099e2
      +++ b/src/rawmidi/rawmidi_local.h
      d099e2
      @@ -37,7 +37,7 @@ typedef struct {
      d099e2
       } snd_rawmidi_ops_t;
      d099e2
       
      d099e2
       struct _snd_rawmidi {
      d099e2
      -	void *dl_handle;
      d099e2
      +	void *open_func;
      d099e2
       	char *name;
      d099e2
       	snd_rawmidi_type_t type;
      d099e2
       	snd_rawmidi_stream_t stream;
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 6efa23f2837a6fa9982b4f34b837401a66941ee3 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 20:45:26 +0200
      d099e2
      Subject: [PATCH 19/25] rawmidi_hw: add sanity check for the invalid stream
      d099e2
       arguments (coverity)
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/rawmidi/rawmidi_hw.c | 2 ++
      d099e2
       1 file changed, 2 insertions(+)
      d099e2
      d099e2
      diff --git a/src/rawmidi/rawmidi_hw.c b/src/rawmidi/rawmidi_hw.c
      d099e2
      index 7cc8c0d1..eaa8a76d 100644
      d099e2
      --- a/src/rawmidi/rawmidi_hw.c
      d099e2
      +++ b/src/rawmidi/rawmidi_hw.c
      d099e2
      @@ -186,6 +186,8 @@ int snd_rawmidi_hw_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
      d099e2
       		*inputp = NULL;
      d099e2
       	if (outputp)
      d099e2
       		*outputp = NULL;
      d099e2
      +	if (!inputp && !outputp)
      d099e2
      +		return -EINVAL;
      d099e2
       	
      d099e2
       	if ((ret = snd_ctl_hw_open(&ctl, NULL, card, 0)) < 0)
      d099e2
       		return ret;
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 0d97f53c25b4dd36d3f6511fae85b597aebc61a1 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 20:52:00 +0200
      d099e2
      Subject: [PATCH 20/25] topology: various coverity fixes
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/topology/ctl.c    |  4 ++--
      d099e2
       src/topology/data.c   | 19 +++++++++++++------
      d099e2
       src/topology/parser.c |  5 +++--
      d099e2
       3 files changed, 18 insertions(+), 10 deletions(-)
      d099e2
      d099e2
      diff --git a/src/topology/ctl.c b/src/topology/ctl.c
      d099e2
      index 9c13b12c..a0962522 100644
      d099e2
      --- a/src/topology/ctl.c
      d099e2
      +++ b/src/topology/ctl.c
      d099e2
      @@ -880,8 +880,8 @@ int tplg_add_enum(snd_tplg_t *tplg, struct snd_tplg_enum_template *enum_ctl,
      d099e2
       	if (enum_ctl->texts != NULL) {
      d099e2
       		for (i = 0; i < num_items; i++) {
      d099e2
       			if (enum_ctl->texts[i] != NULL)
      d099e2
      -				strncpy(ec->texts[i], enum_ctl->texts[i],
      d099e2
      -					SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
      d099e2
      +				snd_strlcpy(ec->texts[i], enum_ctl->texts[i],
      d099e2
      +					    SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
      d099e2
       		}
      d099e2
       	}
      d099e2
       
      d099e2
      diff --git a/src/topology/data.c b/src/topology/data.c
      d099e2
      index fd72abbb..aa2b87e7 100644
      d099e2
      --- a/src/topology/data.c
      d099e2
      +++ b/src/topology/data.c
      d099e2
      @@ -124,12 +124,12 @@ static int tplg_parse_data_file(snd_config_t *cfg, struct tplg_elem *elem)
      d099e2
       
      d099e2
       	if (fclose(fp) == EOF) {
      d099e2
       		SNDERR("Cannot close data file.");
      d099e2
      -		ret = -errno;
      d099e2
      -		goto err;
      d099e2
      +		return -errno;
      d099e2
       	}
      d099e2
       	return 0;
      d099e2
       
      d099e2
       err:
      d099e2
      +	fclose(fp);
      d099e2
       	if (priv)
      d099e2
       		free(priv);
      d099e2
       	return ret;
      d099e2
      @@ -422,7 +422,7 @@ static unsigned int get_tuple_size(int type)
      d099e2
       static int copy_tuples(struct tplg_elem *elem,
      d099e2
       	struct tplg_vendor_tuples *tuples, struct tplg_vendor_tokens *tokens)
      d099e2
       {
      d099e2
      -	struct snd_soc_tplg_private *priv = elem->data;
      d099e2
      +	struct snd_soc_tplg_private *priv = elem->data, *priv2;
      d099e2
       	struct tplg_tuple_set *tuple_set;
      d099e2
       	struct tplg_tuple *tuple;
      d099e2
       	struct snd_soc_tplg_vendor_array *array;
      d099e2
      @@ -447,10 +447,17 @@ static int copy_tuples(struct tplg_elem *elem,
      d099e2
       			return -EINVAL;
      d099e2
       		}
      d099e2
       
      d099e2
      -		if (priv != NULL)
      d099e2
      -			priv = realloc(priv, sizeof(*priv) + size);
      d099e2
      -		else
      d099e2
      +		if (priv != NULL) {
      d099e2
      +			priv2 = realloc(priv, sizeof(*priv) + size);
      d099e2
      +			if (priv2 == NULL) {
      d099e2
      +				free(priv);
      d099e2
      +				priv = NULL;
      d099e2
      +			} else {
      d099e2
      +				priv = priv2;
      d099e2
      +			}
      d099e2
      +		} else {
      d099e2
       			priv = calloc(1, sizeof(*priv) + size);
      d099e2
      +		}
      d099e2
       		if (!priv)
      d099e2
       			return -ENOMEM;
      d099e2
       
      d099e2
      diff --git a/src/topology/parser.c b/src/topology/parser.c
      d099e2
      index cfc20e00..a7cff1c3 100644
      d099e2
      --- a/src/topology/parser.c
      d099e2
      +++ b/src/topology/parser.c
      d099e2
      @@ -237,8 +237,9 @@ static int tplg_load_config(const char *file, snd_config_t **cfg)
      d099e2
       
      d099e2
       	ret = snd_input_stdio_attach(&in, fp, 1);
      d099e2
       	if (ret < 0) {
      d099e2
      +		fclose(fp);
      d099e2
       		SNDERR("error: could not attach stdio %s", file);
      d099e2
      -		goto err;
      d099e2
      +		return ret;
      d099e2
       	}
      d099e2
       	ret = snd_config_top(&top);
      d099e2
       	if (ret < 0)
      d099e2
      @@ -261,7 +262,7 @@ static int tplg_load_config(const char *file, snd_config_t **cfg)
      d099e2
       err_load:
      d099e2
       	snd_config_delete(top);
      d099e2
       err:
      d099e2
      -	fclose(fp);
      d099e2
      +	snd_input_close(in);
      d099e2
       	return ret;
      d099e2
       }
      d099e2
       
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From ed156a218644e3334bc452ef2bc948409735c330 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Fri, 24 May 2019 21:11:00 +0200
      d099e2
      Subject: [PATCH 21/25] ucm: coverity fixes
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/ucm/parser.c | 18 ++++++++++++++----
      d099e2
       src/ucm/utils.c  | 12 +++++++++---
      d099e2
       2 files changed, 23 insertions(+), 7 deletions(-)
      d099e2
      d099e2
      diff --git a/src/ucm/parser.c b/src/ucm/parser.c
      d099e2
      index ad6bcec7..61d5d7f9 100644
      d099e2
      --- a/src/ucm/parser.c
      d099e2
      +++ b/src/ucm/parser.c
      d099e2
      @@ -1114,7 +1114,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
      d099e2
       			if (err < 0) {
      d099e2
       				uc_error("error: %s failed to parse verb",
      d099e2
       						file);
      d099e2
      -				return err;
      d099e2
      +				goto _err;
      d099e2
       			}
      d099e2
       			continue;
      d099e2
       		}
      d099e2
      @@ -1126,7 +1126,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
      d099e2
       			if (err < 0) {
      d099e2
       				uc_error("error: %s failed to parse device",
      d099e2
       						file);
      d099e2
      -				return err;
      d099e2
      +				goto _err;
      d099e2
       			}
      d099e2
       			continue;
      d099e2
       		}
      d099e2
      @@ -1138,18 +1138,24 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
      d099e2
       			if (err < 0) {
      d099e2
       				uc_error("error: %s failed to parse modifier",
      d099e2
       						file);
      d099e2
      -				return err;
      d099e2
      +				goto _err;
      d099e2
       			}
      d099e2
       			continue;
      d099e2
       		}
      d099e2
       	}
      d099e2
       
      d099e2
      +	snd_config_delete(cfg);
      d099e2
      +
      d099e2
       	/* use case verb must have at least 1 device */
      d099e2
       	if (list_empty(&verb->device_list)) {
      d099e2
       		uc_error("error: no use case device defined", file);
      d099e2
       		return -EINVAL;
      d099e2
       	}
      d099e2
       	return 0;
      d099e2
      +
      d099e2
      +       _err:
      d099e2
      +	snd_config_delete(cfg);
      d099e2
      +	return err;
      d099e2
       }
      d099e2
       
      d099e2
       /*
      d099e2
      @@ -1399,6 +1405,7 @@ next_card:
      d099e2
       
      d099e2
       	return -1;
      d099e2
       }
      d099e2
      +
      d099e2
       static int load_master_config(const char *card_name, snd_config_t **cfg)
      d099e2
       {
      d099e2
       	char filename[MAX_FILE];
      d099e2
      @@ -1610,8 +1617,11 @@ int uc_mgr_scan_master_configs(const char **_list[])
      d099e2
       	}
      d099e2
       	free(namelist);
      d099e2
       
      d099e2
      -	if (err >= 0)
      d099e2
      +	if (err >= 0) {
      d099e2
       		*_list = list;
      d099e2
      +	} else {
      d099e2
      +		free(list);
      d099e2
      +	}
      d099e2
       
      d099e2
       	return err;
      d099e2
       }
      d099e2
      diff --git a/src/ucm/utils.c b/src/ucm/utils.c
      d099e2
      index 14227e0a..efd5a979 100644
      d099e2
      --- a/src/ucm/utils.c
      d099e2
      +++ b/src/ucm/utils.c
      d099e2
      @@ -58,14 +58,18 @@ int uc_mgr_config_load(const char *file, snd_config_t **cfg)
      d099e2
       	int err;
      d099e2
       
      d099e2
       	fp = fopen(file, "r");
      d099e2
      -	err = fp == NULL ? -errno : snd_input_stdio_attach(&in, fp, 1);
      d099e2
      -	if (err < 0) {
      d099e2
      +	if (!fp) {
      d099e2
      +		err = -errno;
      d099e2
      +  __err0:
      d099e2
       		uc_error("could not open configuration file %s", file);
      d099e2
       		return err;
      d099e2
       	}
      d099e2
      +	err = snd_input_stdio_attach(&in, fp, 1);
      d099e2
      +	if (err < 0)
      d099e2
      +		goto __err0;
      d099e2
       	err = snd_config_top(&top);
      d099e2
       	if (err < 0)
      d099e2
      -		return err;
      d099e2
      +		goto __err1;
      d099e2
       
      d099e2
       	default_path = getenv(ALSA_CONFIG_UCM_VAR);
      d099e2
       	if (!default_path || !*default_path)
      d099e2
      @@ -88,6 +92,8 @@ int uc_mgr_config_load(const char *file, snd_config_t **cfg)
      d099e2
       
      d099e2
        __err2:
      d099e2
               snd_config_delete(top);
      d099e2
      + __err1:
      d099e2
      +	snd_input_close(in);
      d099e2
       	return err;
      d099e2
       }
      d099e2
       
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 022c790aabc300eabad4da8947a3f2bdadce41e1 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Mon, 27 May 2019 13:57:12 +0200
      d099e2
      Subject: [PATCH 22/25] pcm_file: coverity fixes (including double locking)
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/pcm/pcm_file.c | 16 ++++++----------
      d099e2
       1 file changed, 6 insertions(+), 10 deletions(-)
      d099e2
      d099e2
      diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
      d099e2
      index 99db3754..54142a3d 100644
      d099e2
      --- a/src/pcm/pcm_file.c
      d099e2
      +++ b/src/pcm/pcm_file.c
      d099e2
      @@ -296,7 +296,10 @@ static int snd_pcm_file_areas_read_infile(snd_pcm_t *pcm,
      d099e2
       		return -ENOMEM;
      d099e2
       	}
      d099e2
       
      d099e2
      -	bytes = read(file->ifd, file->rbuf, snd_pcm_frames_to_bytes(pcm, frames));
      d099e2
      +	bytes = snd_pcm_frames_to_bytes(pcm, frames);
      d099e2
      +	if (bytes < 0)
      d099e2
      +		return bytes;
      d099e2
      +	bytes = read(file->ifd, file->rbuf, bytes);
      d099e2
       	if (bytes < 0) {
      d099e2
       		SYSERR("read from file failed, error: %d", bytes);
      d099e2
       		return bytes;
      d099e2
      @@ -589,18 +592,14 @@ static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pc
      d099e2
       	snd_pcm_channel_area_t areas[pcm->channels];
      d099e2
       	snd_pcm_sframes_t frames;
      d099e2
       
      d099e2
      -	__snd_pcm_lock(pcm);
      d099e2
      -
      d099e2
       	frames = _snd_pcm_readi(file->gen.slave, buffer, size);
      d099e2
      -	if (frames <= 0) {
      d099e2
      -		__snd_pcm_unlock(pcm);
      d099e2
      +	if (frames <= 0)
      d099e2
       		return frames;
      d099e2
      -	}
      d099e2
       
      d099e2
       	snd_pcm_areas_from_buf(pcm, areas, buffer);
      d099e2
       	snd_pcm_file_areas_read_infile(pcm, areas, 0, frames);
      d099e2
      +	__snd_pcm_lock(pcm);
      d099e2
       	snd_pcm_file_add_frames(pcm, areas, 0, frames);
      d099e2
      -
      d099e2
       	__snd_pcm_unlock(pcm);
      d099e2
       
      d099e2
       	return frames;
      d099e2
      @@ -654,9 +653,6 @@ static int snd_pcm_file_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t
      d099e2
       	snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
      d099e2
       {
      d099e2
       	snd_pcm_file_t *file = pcm->private_data;
      d099e2
      -	snd_pcm_channel_area_t areas_if[pcm->channels];
      d099e2
      -	snd_pcm_uframes_t frames_if;
      d099e2
      -	void *buffer = NULL;
      d099e2
       	int result;
      d099e2
       
      d099e2
       	result = snd_pcm_mmap_begin(file->gen.slave, areas, offset, frames);
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From c6e7fd8b1e0d8729c7220734ca0b529c35d926ed Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Mon, 27 May 2019 14:05:12 +0200
      d099e2
      Subject: [PATCH 23/25] topology: next round of coverity fixes
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/topology/data.c   | 5 ++---
      d099e2
       src/topology/parser.c | 7 +++++--
      d099e2
       2 files changed, 7 insertions(+), 5 deletions(-)
      d099e2
      d099e2
      diff --git a/src/topology/data.c b/src/topology/data.c
      d099e2
      index aa2b87e7..b3f4421f 100644
      d099e2
      --- a/src/topology/data.c
      d099e2
      +++ b/src/topology/data.c
      d099e2
      @@ -88,8 +88,7 @@ static int tplg_parse_data_file(snd_config_t *cfg, struct tplg_elem *elem)
      d099e2
       	if (fp == NULL) {
      d099e2
       		SNDERR("error: invalid data file path '%s'\n",
      d099e2
       			filename);
      d099e2
      -		ret = -errno;
      d099e2
      -		goto err;
      d099e2
      +		return -errno;
      d099e2
       	}
      d099e2
       
      d099e2
       	fseek(fp, 0L, SEEK_END);
      d099e2
      @@ -463,6 +462,7 @@ static int copy_tuples(struct tplg_elem *elem,
      d099e2
       
      d099e2
       		off = priv->size;
      d099e2
       		priv->size = size; /* update private data size */
      d099e2
      +		elem->data = priv;
      d099e2
       
      d099e2
       		array = (struct snd_soc_tplg_vendor_array *)(priv->data + off);
      d099e2
       		array->size = set_size;
      d099e2
      @@ -499,7 +499,6 @@ static int copy_tuples(struct tplg_elem *elem,
      d099e2
       		}
      d099e2
       	}
      d099e2
       
      d099e2
      -	elem->data = priv;
      d099e2
       	return 0;
      d099e2
       }
      d099e2
       
      d099e2
      diff --git a/src/topology/parser.c b/src/topology/parser.c
      d099e2
      index a7cff1c3..5940692d 100644
      d099e2
      --- a/src/topology/parser.c
      d099e2
      +++ b/src/topology/parser.c
      d099e2
      @@ -253,8 +253,10 @@ static int tplg_load_config(const char *file, snd_config_t **cfg)
      d099e2
       	}
      d099e2
       
      d099e2
       	ret = snd_input_close(in);
      d099e2
      -	if (ret < 0)
      d099e2
      +	if (ret < 0) {
      d099e2
      +		in = NULL;
      d099e2
       		goto err_load;
      d099e2
      +	}
      d099e2
       
      d099e2
       	*cfg = top;
      d099e2
       	return 0;
      d099e2
      @@ -262,7 +264,8 @@ static int tplg_load_config(const char *file, snd_config_t **cfg)
      d099e2
       err_load:
      d099e2
       	snd_config_delete(top);
      d099e2
       err:
      d099e2
      -	snd_input_close(in);
      d099e2
      +	if (in)
      d099e2
      +		snd_input_close(in);
      d099e2
       	return ret;
      d099e2
       }
      d099e2
       
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From ac6df1106c314de5d027176d910b9bc43a1fa7f9 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Mon, 27 May 2019 20:10:32 +0200
      d099e2
      Subject: [PATCH 24/25] pcm_file: another locking fix (coverity)
      d099e2
      d099e2
      Signed-off-by: Jaroslav Kysela <perex@perex.cz>
      d099e2
      ---
      d099e2
       src/pcm/pcm_file.c | 8 +++-----
      d099e2
       1 file changed, 3 insertions(+), 5 deletions(-)
      d099e2
      d099e2
      diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
      d099e2
      index 54142a3d..1ef80b59 100644
      d099e2
      --- a/src/pcm/pcm_file.c
      d099e2
      +++ b/src/pcm/pcm_file.c
      d099e2
      @@ -612,18 +612,16 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm
      d099e2
       	snd_pcm_channel_area_t areas[pcm->channels];
      d099e2
       	snd_pcm_sframes_t frames;
      d099e2
       
      d099e2
      -	__snd_pcm_lock(pcm);
      d099e2
       	frames = _snd_pcm_readn(file->gen.slave, bufs, size);
      d099e2
      -	if (frames <= 0) {
      d099e2
      -		__snd_pcm_unlock(pcm);
      d099e2
      +	if (frames <= 0)
      d099e2
       		return frames;
      d099e2
      -	}
      d099e2
       
      d099e2
       	snd_pcm_areas_from_bufs(pcm, areas, bufs);
      d099e2
       	snd_pcm_file_areas_read_infile(pcm, areas, 0, frames);
      d099e2
      +	__snd_pcm_lock(pcm);
      d099e2
       	snd_pcm_file_add_frames(pcm, areas, 0, frames);
      d099e2
      -
      d099e2
       	__snd_pcm_unlock(pcm);
      d099e2
      +
      d099e2
       	return frames;
      d099e2
       }
      d099e2
       
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2
      d099e2
      d099e2
      From 5905af199670ca34eaaafbd3319d94d230b7e4d4 Mon Sep 17 00:00:00 2001
      d099e2
      From: Jaroslav Kysela <perex@perex.cz>
      d099e2
      Date: Mon, 27 May 2019 20:10:52 +0200
      d099e2
      Subject: [PATCH 25/25] ucm: another coverity fix in uc_mgr_config_load()
      d099e2
      d099e2
      ---
      d099e2
       src/ucm/utils.c | 9 ++++++---
      d099e2
       1 file changed, 6 insertions(+), 3 deletions(-)
      d099e2
      d099e2
      diff --git a/src/ucm/utils.c b/src/ucm/utils.c
      d099e2
      index efd5a979..5607304e 100644
      d099e2
      --- a/src/ucm/utils.c
      d099e2
      +++ b/src/ucm/utils.c
      d099e2
      @@ -85,15 +85,18 @@ int uc_mgr_config_load(const char *file, snd_config_t **cfg)
      d099e2
       		goto __err2;
      d099e2
       	}
      d099e2
       	err = snd_input_close(in);
      d099e2
      -	if (err < 0)
      d099e2
      +	if (err < 0) {
      d099e2
      +		in = NULL;
      d099e2
       		goto __err2;
      d099e2
      +	}
      d099e2
       	*cfg = top;
      d099e2
       	return 0;
      d099e2
       
      d099e2
        __err2:
      d099e2
      -        snd_config_delete(top);
      d099e2
      +	snd_config_delete(top);
      d099e2
        __err1:
      d099e2
      -	snd_input_close(in);
      d099e2
      +	if (in)
      d099e2
      +		snd_input_close(in);
      d099e2
       	return err;
      d099e2
       }
      d099e2
       
      d099e2
      -- 
      d099e2
      2.20.1
      d099e2