Blame SOURCES/alsa-git.patch

c2cdce
From ad8c8e5503980295dd8e5e54a6285d2d7e32eb1e Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 22 Oct 2020 20:57:32 +0200
c2cdce
Subject: [PATCH 01/49] dlmisc: the snd_plugin_dir_set / snd_plugin_dir must be
c2cdce
 declared even for \!DL_ORIGIN_AVAILABLE
c2cdce
c2cdce
Fixes: 8580c081c2 ("dlsym: add support for ALSA_PLUGIN_DIR environment variable")
c2cdce
BugLink: https://github.com/alsa-project/alsa-lib/issues/91
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/dlmisc.c | 2 --
c2cdce
 1 file changed, 2 deletions(-)
c2cdce
c2cdce
diff --git a/src/dlmisc.c b/src/dlmisc.c
c2cdce
index c9517c55..f20eb593 100644
c2cdce
--- a/src/dlmisc.c
c2cdce
+++ b/src/dlmisc.c
c2cdce
@@ -42,11 +42,9 @@
c2cdce
 #ifndef PIC
c2cdce
 struct snd_dlsym_link *snd_dlsym_start = NULL;
c2cdce
 #endif
c2cdce
-#ifdef DL_ORIGIN_AVAILABLE
c2cdce
 static int snd_plugin_dir_set = 0;
c2cdce
 static char *snd_plugin_dir = NULL;
c2cdce
 #endif
c2cdce
-#endif
c2cdce
 
c2cdce
 #if defined(DL_ORIGIN_AVAILABLE) && defined(HAVE_LIBPTHREAD)
c2cdce
 static pthread_mutex_t snd_dlpath_mutex = PTHREAD_MUTEX_INITIALIZER;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 1d993b37ab4e0b9b6e6b795d7be84ce97b29e20b Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 29 Oct 2020 20:31:19 +0100
c2cdce
Subject: [PATCH 02/49] dlmisc: fix snd_plugin_dir locking for not
c2cdce
 DL_ORIGIN_AVAILABLE
c2cdce
c2cdce
Fixes: 8580c081c2 ("dlsym: add support for ALSA_PLUGIN_DIR environment variable")
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/dlmisc.c | 4 +---
c2cdce
 1 file changed, 1 insertion(+), 3 deletions(-)
c2cdce
c2cdce
diff --git a/src/dlmisc.c b/src/dlmisc.c
c2cdce
index f20eb593..1dd91356 100644
c2cdce
--- a/src/dlmisc.c
c2cdce
+++ b/src/dlmisc.c
c2cdce
@@ -46,7 +46,7 @@ static int snd_plugin_dir_set = 0;
c2cdce
 static char *snd_plugin_dir = NULL;
c2cdce
 #endif
c2cdce
 
c2cdce
-#if defined(DL_ORIGIN_AVAILABLE) && defined(HAVE_LIBPTHREAD)
c2cdce
+#ifdef HAVE_LIBPTHREAD
c2cdce
 static pthread_mutex_t snd_dlpath_mutex = PTHREAD_MUTEX_INITIALIZER;
c2cdce
 
c2cdce
 static inline void snd_dlpath_lock(void)
c2cdce
@@ -440,12 +440,10 @@ void snd_dlobj_cache_cleanup(void)
c2cdce
 		free(c);
c2cdce
 	}
c2cdce
 	snd_dlobj_unlock();
c2cdce
-#ifdef DL_ORIGIN_AVAILABLE
c2cdce
 	snd_dlpath_lock();
c2cdce
 	snd_plugin_dir_set = 0;
c2cdce
 	free(snd_plugin_dir);
c2cdce
 	snd_plugin_dir = NULL;
c2cdce
 	snd_dlpath_unlock();
c2cdce
-#endif
c2cdce
 }
c2cdce
 #endif
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 2757191e3b85d491705b31c6ecca2dbd96d26ade Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 29 Oct 2020 20:34:17 +0100
c2cdce
Subject: [PATCH 03/49] pcm: snd_pcm_mmap_readi - fix typo in comment
c2cdce
c2cdce
\param size frames to be *read*
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_mmap.c | 2 +-
c2cdce
 1 file changed, 1 insertion(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c
c2cdce
index 9600c383..9cbaae05 100644
c2cdce
--- a/src/pcm/pcm_mmap.c
c2cdce
+++ b/src/pcm/pcm_mmap.c
c2cdce
@@ -183,7 +183,7 @@ snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_ufram
c2cdce
  * \brief Read interleaved frames from a PCM using direct buffer (mmap)
c2cdce
  * \param pcm PCM handle
c2cdce
  * \param buffer frames containing buffer
c2cdce
- * \param size frames to be written
c2cdce
+ * \param size frames to be read
c2cdce
  * \return a positive number of frames actually read otherwise a
c2cdce
  * negative error code
c2cdce
  * \retval -EBADFD PCM is not in the right state (#SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING)
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 39bd0e1a5be3620f9123f7fe72ffa6cb7d463b21 Mon Sep 17 00:00:00 2001
c2cdce
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
c2cdce
Date: Thu, 12 Nov 2020 10:29:38 -0600
c2cdce
Subject: [PATCH 04/49] topology: use inclusive language for bclk
c2cdce
c2cdce
use bclk_provider for structure fields, 'codec_provider' and
c2cdce
'codec_consumer' for options and modify #defines to use CP and CC
c2cdce
suffixes.
c2cdce
c2cdce
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 include/sound/uapi/asoc.h | 11 +++++++----
c2cdce
 include/topology.h        |  2 +-
c2cdce
 src/topology/pcm.c        | 36 ++++++++++++++++++++++++++----------
c2cdce
 3 files changed, 34 insertions(+), 15 deletions(-)
c2cdce
c2cdce
diff --git a/include/sound/uapi/asoc.h b/include/sound/uapi/asoc.h
c2cdce
index 4efb4ec4..ceafb1a9 100644
c2cdce
--- a/include/sound/uapi/asoc.h
c2cdce
+++ b/include/sound/uapi/asoc.h
c2cdce
@@ -169,10 +169,13 @@
c2cdce
 #define SND_SOC_TPLG_LNK_FLGBIT_VOICE_WAKEUP            (1 << 3)
c2cdce
 
c2cdce
 /* DAI topology BCLK parameter
c2cdce
- * For the backwards capability, by default codec is bclk master
c2cdce
+ * For the backwards capability, by default codec is bclk provider
c2cdce
  */
c2cdce
-#define SND_SOC_TPLG_BCLK_CM         0 /* codec is bclk master */
c2cdce
-#define SND_SOC_TPLG_BCLK_CS         1 /* codec is bclk slave */
c2cdce
+#define SND_SOC_TPLG_BCLK_CP         0 /* codec is bclk provider */
c2cdce
+#define SND_SOC_TPLG_BCLK_CC         1 /* codec is bclk consumer */
c2cdce
+/* keep previous definitions for compatibility */
c2cdce
+#define SND_SOC_TPLG_BCLK_CM         SND_SOC_TPLG_BCLK_CP
c2cdce
+#define SND_SOC_TPLG_BCLK_CS         SND_SOC_TPLG_BCLK_CC
c2cdce
 
c2cdce
 /* DAI topology FSYNC parameter
c2cdce
  * For the backwards capability, by default codec is fsync master
c2cdce
@@ -335,7 +338,7 @@ struct snd_soc_tplg_hw_config {
c2cdce
 	__u8 clock_gated;	/* SND_SOC_TPLG_DAI_CLK_GATE_ value */
c2cdce
 	__u8 invert_bclk;	/* 1 for inverted BCLK, 0 for normal */
c2cdce
 	__u8 invert_fsync;	/* 1 for inverted frame clock, 0 for normal */
c2cdce
-	__u8 bclk_master;	/* SND_SOC_TPLG_BCLK_ value */
c2cdce
+	__u8 bclk_provider;	/* SND_SOC_TPLG_BCLK_ value */
c2cdce
 	__u8 fsync_master;	/* SND_SOC_TPLG_FSYNC_ value */
c2cdce
 	__u8 mclk_direction;    /* SND_SOC_TPLG_MCLK_ value */
c2cdce
 	__le16 reserved;	/* for 32bit alignment */
c2cdce
diff --git a/include/topology.h b/include/topology.h
c2cdce
index 1f52e66e..6c970649 100644
c2cdce
--- a/include/topology.h
c2cdce
+++ b/include/topology.h
c2cdce
@@ -1028,7 +1028,7 @@ struct snd_tplg_hw_config_template {
c2cdce
 	unsigned char clock_gated;      /* SND_SOC_TPLG_DAI_CLK_GATE_ value */
c2cdce
 	unsigned char  invert_bclk;     /* 1 for inverted BCLK, 0 for normal */
c2cdce
 	unsigned char  invert_fsync;    /* 1 for inverted frame clock, 0 for normal */
c2cdce
-	unsigned char  bclk_master;     /* SND_SOC_TPLG_BCLK_ value */
c2cdce
+	unsigned char  bclk_provider;   /* SND_SOC_TPLG_BCLK_ value */
c2cdce
 	unsigned char  fsync_master;    /* SND_SOC_TPLG_FSYNC_ value */
c2cdce
 	unsigned char  mclk_direction;  /* SND_SOC_TPLG_MCLK_ value */
c2cdce
 	unsigned short reserved;        /* for 32bit alignment */
c2cdce
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
c2cdce
index 191b7a0a..f05df348 100644
c2cdce
--- a/src/topology/pcm.c
c2cdce
+++ b/src/topology/pcm.c
c2cdce
@@ -1411,6 +1411,7 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
c2cdce
 	snd_config_t *n;
c2cdce
 	const char *id, *val = NULL;
c2cdce
 	int ret, ival;
c2cdce
+	bool provider_legacy;
c2cdce
 
c2cdce
 	elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_HW_CONFIG);
c2cdce
 	if (!elem)
c2cdce
@@ -1451,8 +1452,15 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
c2cdce
 			continue;
c2cdce
 		}
c2cdce
 
c2cdce
-		if (strcmp(id, "bclk") == 0 ||
c2cdce
-		    strcmp(id, "bclk_master") == 0) {
c2cdce
+		provider_legacy = false;
c2cdce
+		if (strcmp(id, "bclk_master") == 0) {
c2cdce
+			SNDERR("deprecated option %s, please use 'bclk'\n", id);
c2cdce
+			provider_legacy = true;
c2cdce
+		}
c2cdce
+
c2cdce
+		if (provider_legacy ||
c2cdce
+		    strcmp(id, "bclk") == 0) {
c2cdce
+
c2cdce
 			if (snd_config_get_string(n, &val) < 0)
c2cdce
 				return -EINVAL;
c2cdce
 
c2cdce
@@ -1462,11 +1470,19 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
c2cdce
 				 */
c2cdce
 				SNDERR("deprecated bclk value '%s'", val);
c2cdce
 
c2cdce
-				hw_cfg->bclk_master = SND_SOC_TPLG_BCLK_CS;
c2cdce
+				hw_cfg->bclk_provider = SND_SOC_TPLG_BCLK_CC;
c2cdce
 			} else if (!strcmp(val, "codec_slave")) {
c2cdce
-				hw_cfg->bclk_master = SND_SOC_TPLG_BCLK_CS;
c2cdce
+				SNDERR("deprecated bclk value '%s', use 'codec_consumer'", val);
c2cdce
+
c2cdce
+				hw_cfg->bclk_provider = SND_SOC_TPLG_BCLK_CC;
c2cdce
+			} else if (!strcmp(val, "codec_consumer")) {
c2cdce
+				hw_cfg->bclk_provider = SND_SOC_TPLG_BCLK_CC;
c2cdce
 			} else if (!strcmp(val, "codec_master")) {
c2cdce
-				hw_cfg->bclk_master = SND_SOC_TPLG_BCLK_CM;
c2cdce
+				SNDERR("deprecated bclk value '%s', use 'codec_provider", val);
c2cdce
+
c2cdce
+				hw_cfg->bclk_provider = SND_SOC_TPLG_BCLK_CP;
c2cdce
+			} else if (!strcmp(val, "codec_provider")) {
c2cdce
+				hw_cfg->bclk_provider = SND_SOC_TPLG_BCLK_CP;
c2cdce
 			}
c2cdce
 			continue;
c2cdce
 		}
c2cdce
@@ -1623,10 +1639,10 @@ int tplg_save_hw_config(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
c2cdce
 	if (err >= 0 && hc->fmt)
c2cdce
 		err = tplg_save_printf(dst, pfx, "\tformat '%s'\n",
c2cdce
 				       get_audio_hw_format_name(hc->fmt));
c2cdce
-	if (err >= 0 && hc->bclk_master)
c2cdce
+	if (err >= 0 && hc->bclk_provider)
c2cdce
 		err = tplg_save_printf(dst, pfx, "\tbclk '%s'\n",
c2cdce
-				       hc->bclk_master == SND_SOC_TPLG_BCLK_CS ?
c2cdce
-						"codec_slave" : "codec_master");
c2cdce
+				       hc->bclk_provider == SND_SOC_TPLG_BCLK_CC ?
c2cdce
+						"codec_consumer" : "codec_provider");
c2cdce
 	if (err >= 0 && hc->bclk_rate)
c2cdce
 		err = tplg_save_printf(dst, pfx, "\tbclk_freq %u\n",
c2cdce
 				       hc->bclk_rate);
c2cdce
@@ -1791,7 +1807,7 @@ static int set_link_hw_config(struct snd_soc_tplg_hw_config *cfg,
c2cdce
 	cfg->clock_gated = tpl->clock_gated;
c2cdce
 	cfg->invert_bclk = tpl->invert_bclk;
c2cdce
 	cfg->invert_fsync = tpl->invert_fsync;
c2cdce
-	cfg->bclk_master = tpl->bclk_master;
c2cdce
+	cfg->bclk_provider = tpl->bclk_provider;
c2cdce
 	cfg->fsync_master = tpl->fsync_master;
c2cdce
 	cfg->mclk_direction = tpl->mclk_direction;
c2cdce
 	cfg->reserved = tpl->reserved;
c2cdce
@@ -2174,7 +2190,7 @@ next:
c2cdce
 		hw->clock_gated = link->hw_config[i].clock_gated;
c2cdce
 		hw->invert_bclk = link->hw_config[i].invert_bclk;
c2cdce
 		hw->invert_fsync = link->hw_config[i].invert_fsync;
c2cdce
-		hw->bclk_master = link->hw_config[i].bclk_master;
c2cdce
+		hw->bclk_provider = link->hw_config[i].bclk_provider;
c2cdce
 		hw->fsync_master = link->hw_config[i].fsync_master;
c2cdce
 		hw->mclk_direction = link->hw_config[i].mclk_direction;
c2cdce
 		hw->mclk_rate = link->hw_config[i].mclk_rate;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 706192341d1d0bbb906d690b227b9dee5c1fc4b5 Mon Sep 17 00:00:00 2001
c2cdce
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
c2cdce
Date: Thu, 12 Nov 2020 10:29:39 -0600
c2cdce
Subject: [PATCH 05/49] topology: use inclusive language for fsync
c2cdce
c2cdce
use fsync_provider for structure fields, 'codec_provider' and
c2cdce
'codec_consumer' for options and modify #defines to use CP and CC
c2cdce
suffixes.
c2cdce
c2cdce
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 include/sound/uapi/asoc.h | 11 +++++++----
c2cdce
 include/topology.h        |  2 +-
c2cdce
 src/topology/pcm.c        | 37 ++++++++++++++++++++++++++-----------
c2cdce
 3 files changed, 34 insertions(+), 16 deletions(-)
c2cdce
c2cdce
diff --git a/include/sound/uapi/asoc.h b/include/sound/uapi/asoc.h
c2cdce
index ceafb1a9..f32c5697 100644
c2cdce
--- a/include/sound/uapi/asoc.h
c2cdce
+++ b/include/sound/uapi/asoc.h
c2cdce
@@ -178,10 +178,13 @@
c2cdce
 #define SND_SOC_TPLG_BCLK_CS         SND_SOC_TPLG_BCLK_CC
c2cdce
 
c2cdce
 /* DAI topology FSYNC parameter
c2cdce
- * For the backwards capability, by default codec is fsync master
c2cdce
+ * For the backwards capability, by default codec is fsync provider
c2cdce
  */
c2cdce
-#define SND_SOC_TPLG_FSYNC_CM         0 /* codec is fsync master */
c2cdce
-#define SND_SOC_TPLG_FSYNC_CS         1 /* codec is fsync slave */
c2cdce
+#define SND_SOC_TPLG_FSYNC_CP         0 /* codec is fsync provider */
c2cdce
+#define SND_SOC_TPLG_FSYNC_CC         1 /* codec is fsync consumer */
c2cdce
+/* keep previous definitions for compatibility */
c2cdce
+#define SND_SOC_TPLG_FSYNC_CM         SND_SOC_TPLG_FSYNC_CP
c2cdce
+#define SND_SOC_TPLG_FSYNC_CS         SND_SOC_TPLG_FSYNC_CC
c2cdce
 
c2cdce
 /*
c2cdce
  * Block Header.
c2cdce
@@ -339,7 +342,7 @@ struct snd_soc_tplg_hw_config {
c2cdce
 	__u8 invert_bclk;	/* 1 for inverted BCLK, 0 for normal */
c2cdce
 	__u8 invert_fsync;	/* 1 for inverted frame clock, 0 for normal */
c2cdce
 	__u8 bclk_provider;	/* SND_SOC_TPLG_BCLK_ value */
c2cdce
-	__u8 fsync_master;	/* SND_SOC_TPLG_FSYNC_ value */
c2cdce
+	__u8 fsync_provider;	/* SND_SOC_TPLG_FSYNC_ value */
c2cdce
 	__u8 mclk_direction;    /* SND_SOC_TPLG_MCLK_ value */
c2cdce
 	__le16 reserved;	/* for 32bit alignment */
c2cdce
 	__le32 mclk_rate;	/* MCLK or SYSCLK freqency in Hz */
c2cdce
diff --git a/include/topology.h b/include/topology.h
c2cdce
index 6c970649..4ade20df 100644
c2cdce
--- a/include/topology.h
c2cdce
+++ b/include/topology.h
c2cdce
@@ -1029,7 +1029,7 @@ struct snd_tplg_hw_config_template {
c2cdce
 	unsigned char  invert_bclk;     /* 1 for inverted BCLK, 0 for normal */
c2cdce
 	unsigned char  invert_fsync;    /* 1 for inverted frame clock, 0 for normal */
c2cdce
 	unsigned char  bclk_provider;   /* SND_SOC_TPLG_BCLK_ value */
c2cdce
-	unsigned char  fsync_master;    /* SND_SOC_TPLG_FSYNC_ value */
c2cdce
+	unsigned char  fsync_provider;  /* SND_SOC_TPLG_FSYNC_ value */
c2cdce
 	unsigned char  mclk_direction;  /* SND_SOC_TPLG_MCLK_ value */
c2cdce
 	unsigned short reserved;        /* for 32bit alignment */
c2cdce
 	unsigned int mclk_rate;	        /* MCLK or SYSCLK freqency in Hz */
c2cdce
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
c2cdce
index f05df348..c8f41862 100644
c2cdce
--- a/src/topology/pcm.c
c2cdce
+++ b/src/topology/pcm.c
c2cdce
@@ -1504,8 +1504,15 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
c2cdce
 			continue;
c2cdce
 		}
c2cdce
 
c2cdce
-		if (strcmp(id, "fsync") == 0 ||
c2cdce
-		    strcmp(id, "fsync_master") == 0) {
c2cdce
+		provider_legacy = false;
c2cdce
+		if (strcmp(id, "fsync_master") == 0) {
c2cdce
+			SNDERR("deprecated option %s, please use 'fsync'\n", id);
c2cdce
+			provider_legacy = true;
c2cdce
+		}
c2cdce
+
c2cdce
+		if (provider_legacy ||
c2cdce
+		    strcmp(id, "fsync") == 0) {
c2cdce
+
c2cdce
 			if (snd_config_get_string(n, &val) < 0)
c2cdce
 				return -EINVAL;
c2cdce
 
c2cdce
@@ -1515,11 +1522,19 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
c2cdce
 				 */
c2cdce
 				SNDERR("deprecated fsync value '%s'", val);
c2cdce
 
c2cdce
-				hw_cfg->fsync_master = SND_SOC_TPLG_FSYNC_CS;
c2cdce
+				hw_cfg->fsync_provider = SND_SOC_TPLG_FSYNC_CC;
c2cdce
 			} else if (!strcmp(val, "codec_slave")) {
c2cdce
-				hw_cfg->fsync_master = SND_SOC_TPLG_FSYNC_CS;
c2cdce
+				SNDERR("deprecated fsync value '%s', use 'codec_consumer'", val);
c2cdce
+
c2cdce
+				hw_cfg->fsync_provider = SND_SOC_TPLG_FSYNC_CC;
c2cdce
+			} else if (!strcmp(val, "codec_consumer")) {
c2cdce
+				hw_cfg->fsync_provider = SND_SOC_TPLG_FSYNC_CC;
c2cdce
 			} else if (!strcmp(val, "codec_master")) {
c2cdce
-				hw_cfg->fsync_master = SND_SOC_TPLG_FSYNC_CM;
c2cdce
+				SNDERR("deprecated fsync value '%s', use 'codec_provider'", val);
c2cdce
+
c2cdce
+				hw_cfg->fsync_provider = SND_SOC_TPLG_FSYNC_CP;
c2cdce
+			} else if (!strcmp(val, "codec_provider")) {
c2cdce
+				hw_cfg->fsync_provider = SND_SOC_TPLG_FSYNC_CP;
c2cdce
 			}
c2cdce
 			continue;
c2cdce
 		}
c2cdce
@@ -1648,10 +1663,10 @@ int tplg_save_hw_config(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
c2cdce
 				       hc->bclk_rate);
c2cdce
 	if (err >= 0 && hc->invert_bclk)
c2cdce
 		err = tplg_save_printf(dst, pfx, "\tbclk_invert 1\n");
c2cdce
-	if (err >= 0 && hc->fsync_master)
c2cdce
-		err = tplg_save_printf(dst, pfx, "\tfsync_master '%s'\n",
c2cdce
-				       hc->fsync_master == SND_SOC_TPLG_FSYNC_CS ?
c2cdce
-						"codec_slave" : "codec_master");
c2cdce
+	if (err >= 0 && hc->fsync_provider)
c2cdce
+		err = tplg_save_printf(dst, pfx, "\tfsync_provider '%s'\n",
c2cdce
+				       hc->fsync_provider == SND_SOC_TPLG_FSYNC_CC ?
c2cdce
+						"codec_consumer" : "codec_provider");
c2cdce
 	if (err >= 0 && hc->fsync_rate)
c2cdce
 		err = tplg_save_printf(dst, pfx, "\tfsync_freq %u\n",
c2cdce
 				       hc->fsync_rate);
c2cdce
@@ -1808,7 +1823,7 @@ static int set_link_hw_config(struct snd_soc_tplg_hw_config *cfg,
c2cdce
 	cfg->invert_bclk = tpl->invert_bclk;
c2cdce
 	cfg->invert_fsync = tpl->invert_fsync;
c2cdce
 	cfg->bclk_provider = tpl->bclk_provider;
c2cdce
-	cfg->fsync_master = tpl->fsync_master;
c2cdce
+	cfg->fsync_provider = tpl->fsync_provider;
c2cdce
 	cfg->mclk_direction = tpl->mclk_direction;
c2cdce
 	cfg->reserved = tpl->reserved;
c2cdce
 	cfg->mclk_rate = tpl->mclk_rate;
c2cdce
@@ -2191,7 +2206,7 @@ next:
c2cdce
 		hw->invert_bclk = link->hw_config[i].invert_bclk;
c2cdce
 		hw->invert_fsync = link->hw_config[i].invert_fsync;
c2cdce
 		hw->bclk_provider = link->hw_config[i].bclk_provider;
c2cdce
-		hw->fsync_master = link->hw_config[i].fsync_master;
c2cdce
+		hw->fsync_provider = link->hw_config[i].fsync_provider;
c2cdce
 		hw->mclk_direction = link->hw_config[i].mclk_direction;
c2cdce
 		hw->mclk_rate = link->hw_config[i].mclk_rate;
c2cdce
 		hw->bclk_rate = link->hw_config[i].bclk_rate;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From e5c350d7bc6f3d45702059c0ae8d32b3603273c1 Mon Sep 17 00:00:00 2001
c2cdce
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
c2cdce
Date: Thu, 12 Nov 2020 10:29:40 -0600
c2cdce
Subject: [PATCH 06/49] topology: use inclusive language in documentation
c2cdce
c2cdce
Use codec_provider and codec_consumer for bclk and fsync
c2cdce
c2cdce
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 include/topology.h | 4 ++--
c2cdce
 1 file changed, 2 insertions(+), 2 deletions(-)
c2cdce
c2cdce
diff --git a/include/topology.h b/include/topology.h
c2cdce
index 4ade20df..d1feee4d 100644
c2cdce
--- a/include/topology.h
c2cdce
+++ b/include/topology.h
c2cdce
@@ -658,8 +658,8 @@ extern "C" {
c2cdce
  *
c2cdce
  *	id "1"				# used for binding to the config
c2cdce
  *	format "I2S"			# physical audio format.
c2cdce
- *	bclk   "master"			# Platform is master of bit clock
c2cdce
- *	fsync  "slave"			# Platform is slave of fsync
c2cdce
+ *	bclk   "codec_provider"		# Codec provides the bit clock
c2cdce
+ *	fsync  "codec_consumer"		# Codec follows the fsync
c2cdce
  * }
c2cdce
  * 
c2cdce
  *
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 7d36895225d09ae26868997382445cc7ad2e9513 Mon Sep 17 00:00:00 2001
c2cdce
From: Jonas Holmberg <jonashg@axis.com>
c2cdce
Date: Wed, 4 Nov 2020 14:49:56 +0100
c2cdce
Subject: [PATCH 07/49] pcm: set the snd_pcm_ioplug_status() tstamp field
c2cdce
c2cdce
Set the status tstamp field so that it can be accessed with
c2cdce
snd_pcm_status_get_htstamp().
c2cdce
c2cdce
Signed-off-by: Jonas Holmberg <jonashg@axis.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 src/pcm/pcm_ioplug.c | 1 +
c2cdce
 1 file changed, 1 insertion(+)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c
c2cdce
index a437ca32..9b1b8ac3 100644
c2cdce
--- a/src/pcm/pcm_ioplug.c
c2cdce
+++ b/src/pcm/pcm_ioplug.c
c2cdce
@@ -115,6 +115,7 @@ static int snd_pcm_ioplug_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 	snd_pcm_ioplug_hw_ptr_update(pcm);
c2cdce
 	status->state = io->data->state;
c2cdce
 	status->trigger_tstamp = io->trigger_tstamp;
c2cdce
+	gettimestamp(&status->tstamp, pcm->tstamp_type);
c2cdce
 	status->avail = snd_pcm_mmap_avail(pcm);
c2cdce
 	status->avail_max = io->avail_max;
c2cdce
 	return 0;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 6d3311fefb1b41c7484fd728e4ad4a6fb5b55ad4 Mon Sep 17 00:00:00 2001
c2cdce
From: Takashi Iwai <tiwai@suse.de>
c2cdce
Date: Thu, 10 Dec 2020 10:36:41 +0100
c2cdce
Subject: [PATCH 08/49] Makefile: Add README.md to EXTRA_DIST
c2cdce
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 Makefile.am | 2 +-
c2cdce
 1 file changed, 1 insertion(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/Makefile.am b/Makefile.am
c2cdce
index c484d4da..ff4c963a 100644
c2cdce
--- a/Makefile.am
c2cdce
+++ b/Makefile.am
c2cdce
@@ -16,7 +16,7 @@ SUBDIRS += alsalisp
c2cdce
 endif
c2cdce
 endif
c2cdce
 SUBDIRS += test utils
c2cdce
-EXTRA_DIST=ChangeLog INSTALL TODO NOTES configure gitcompile libtool \
c2cdce
+EXTRA_DIST=README.md ChangeLog INSTALL TODO NOTES configure gitcompile libtool \
c2cdce
 	   depcomp version MEMORY-LEAK m4/attributes.m4
c2cdce
 AUTOMAKE_OPTIONS=foreign
c2cdce
 
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From ea02dbd20a535085638c63c6b8bec94e628486c4 Mon Sep 17 00:00:00 2001
c2cdce
From: David Henningsson <diwic@ubuntu.com>
c2cdce
Date: Wed, 16 Dec 2020 19:55:22 +0100
c2cdce
Subject: [PATCH 09/49] pcm: Add snd_pcm_audio_tstamp_type_t constants
c2cdce
c2cdce
These are mostly a copy-paste from the kernel headers. But since functions
c2cdce
snd_pcm_audio_tstamp_config make use of these they should be added to the
c2cdce
public API as well.
c2cdce
c2cdce
Reported-by: Alex Moon <alex.r.moon@gmail.com>
c2cdce
Signed-off-by: David Henningsson <diwic@ubuntu.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 include/pcm.h | 14 ++++++++++++++
c2cdce
 1 file changed, 14 insertions(+)
c2cdce
c2cdce
diff --git a/include/pcm.h b/include/pcm.h
c2cdce
index 5b078231..cf1eea8b 100644
c2cdce
--- a/include/pcm.h
c2cdce
+++ b/include/pcm.h
c2cdce
@@ -350,6 +350,20 @@ typedef enum _snd_pcm_tstamp_type {
c2cdce
 	SND_PCM_TSTAMP_TYPE_LAST = SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW,
c2cdce
 } snd_pcm_tstamp_type_t;
c2cdce
 
c2cdce
+typedef enum _snd_pcm_audio_tstamp_type {
c2cdce
+	/**
c2cdce
+	 * first definition for backwards compatibility only,
c2cdce
+	 * maps to wallclock/link time for HDAudio playback and DEFAULT/DMA time for everything else
c2cdce
+	 */
c2cdce
+	SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT = 0,
c2cdce
+	SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT = 1,           /**< DMA time, reported as per hw_ptr */
c2cdce
+	SND_PCM_AUDIO_TSTAMP_TYPE_LINK = 2,	           /**< link time reported by sample or wallclock counter, reset on startup */
c2cdce
+	SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE = 3,	   /**< link time reported by sample or wallclock counter, not reset on startup */
c2cdce
+	SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED = 4,    /**< link time estimated indirectly */
c2cdce
+	SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED = 5, /**< link time synchronized with system time */
c2cdce
+	SND_PCM_AUDIO_TSTAMP_TYPE_LAST = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED
c2cdce
+} snd_pcm_audio_tstamp_type_t;
c2cdce
+
c2cdce
 typedef struct _snd_pcm_audio_tstamp_config {
c2cdce
 	/* 5 of max 16 bits used */
c2cdce
 	unsigned int type_requested:4;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From dcda999d0000cbdabe61d3d175943b5f23c30057 Mon Sep 17 00:00:00 2001
c2cdce
From: David Henningsson <diwic@ubuntu.com>
c2cdce
Date: Wed, 16 Dec 2020 20:02:52 +0100
c2cdce
Subject: [PATCH 10/49] test/audio_time: Make use of SND_PCM_AUDIO_TSTAMP_TYPE
c2cdce
 constants
c2cdce
c2cdce
Also fixup the usage row which seemed wrong to me.
c2cdce
c2cdce
Signed-off-by: David Henningsson <diwic@ubuntu.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 test/audio_time.c | 26 +++++++++++++-------------
c2cdce
 1 file changed, 13 insertions(+), 13 deletions(-)
c2cdce
c2cdce
diff --git a/test/audio_time.c b/test/audio_time.c
c2cdce
index 530922d9..e4d4a944 100644
c2cdce
--- a/test/audio_time.c
c2cdce
+++ b/test/audio_time.c
c2cdce
@@ -32,7 +32,7 @@ static void usage(char *command)
c2cdce
 		"-d, --delay             add delay \n"
c2cdce
 		"-D, --device=NAME       select PCM by name \n"
c2cdce
 		"-p, --playback          playback tstamps \n"
c2cdce
-		"-t, --ts_type=TYPE      Default(0),link(1),link_estimated(2),synchronized(3) \n"
c2cdce
+		"-t, --ts_type=TYPE      Compat(0),default(1),link(2),link_absolute(3),link_estimated(4),link_synchronized(5) \n"
c2cdce
 		"-r, --report            show audio timestamp and accuracy validity\n"
c2cdce
 		, command);
c2cdce
 }
c2cdce
@@ -201,17 +201,17 @@ int main(int argc, char *argv[])
c2cdce
 			goto _exit;
c2cdce
 		}
c2cdce
 
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 0))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT))
c2cdce
 			printf("Playback supports audio compat timestamps\n");
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 1))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT))
c2cdce
 			printf("Playback supports audio default timestamps\n");
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 2))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_LINK))
c2cdce
 			printf("Playback supports audio link timestamps\n");
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 3))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE))
c2cdce
 			printf("Playback supports audio link absolute timestamps\n");
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 4))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED))
c2cdce
 			printf("Playback supports audio link estimated timestamps\n");
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, 5))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_p, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED))
c2cdce
 			printf("Playback supports audio link synchronized timestamps\n");
c2cdce
 
c2cdce
 		snd_pcm_sw_params_alloca(&swparams_p);
c2cdce
@@ -269,17 +269,17 @@ int main(int argc, char *argv[])
c2cdce
 			goto _exit;
c2cdce
 		}
c2cdce
 
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 0))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT))
c2cdce
 			printf("Capture supports audio compat timestamps\n");
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 1))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT))
c2cdce
 			printf("Capture supports audio default timestamps\n");
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 2))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_LINK))
c2cdce
 			printf("Capture supports audio link timestamps\n");
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 3))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE))
c2cdce
 			printf("Capture supports audio link absolute timestamps\n");
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 4))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED))
c2cdce
 			printf("Capture supports audio link estimated timestamps\n");
c2cdce
-		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, 5))
c2cdce
+		if (snd_pcm_hw_params_supports_audio_ts_type(hwparams_c, SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED))
c2cdce
 			printf("Capture supports audio link synchronized timestamps\n");
c2cdce
 
c2cdce
 		snd_pcm_sw_params_alloca(&swparams_c);
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From a9cbfecd87777d76a83e5a912ca9bdcf48e31fa9 Mon Sep 17 00:00:00 2001
c2cdce
From: Takashi Iwai <tiwai@suse.de>
c2cdce
Date: Tue, 22 Dec 2020 16:10:16 +0100
c2cdce
Subject: [PATCH 11/49] pcm: Fix a typo in SND_PCM_AUDIO_TSTAMP_TYPE_LAST
c2cdce
 definition
c2cdce
c2cdce
It was wrongly defined with SNDRV_ prefix.  Fix it.
c2cdce
c2cdce
Fixes: ea02dbd20a53 ("pcm: Add snd_pcm_audio_tstamp_type_t constants")
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 include/pcm.h | 2 +-
c2cdce
 1 file changed, 1 insertion(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/include/pcm.h b/include/pcm.h
c2cdce
index cf1eea8b..e300b951 100644
c2cdce
--- a/include/pcm.h
c2cdce
+++ b/include/pcm.h
c2cdce
@@ -361,7 +361,7 @@ typedef enum _snd_pcm_audio_tstamp_type {
c2cdce
 	SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE = 3,	   /**< link time reported by sample or wallclock counter, not reset on startup */
c2cdce
 	SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED = 4,    /**< link time estimated indirectly */
c2cdce
 	SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED = 5, /**< link time synchronized with system time */
c2cdce
-	SND_PCM_AUDIO_TSTAMP_TYPE_LAST = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED
c2cdce
+	SND_PCM_AUDIO_TSTAMP_TYPE_LAST = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED
c2cdce
 } snd_pcm_audio_tstamp_type_t;
c2cdce
 
c2cdce
 typedef struct _snd_pcm_audio_tstamp_config {
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 5275d170e05639473e68e5feb349aec65bf26428 Mon Sep 17 00:00:00 2001
c2cdce
From: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Date: Sat, 26 Dec 2020 14:35:39 -0700
c2cdce
Subject: [PATCH 12/49] conf: fix use after free in
c2cdce
 _snd_config_load_with_include
c2cdce
c2cdce
Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 src/conf.c | 4 +++-
c2cdce
 1 file changed, 3 insertions(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/conf.c b/src/conf.c
c2cdce
index 7df2b4e7..44d1bfde 100644
c2cdce
--- a/src/conf.c
c2cdce
+++ b/src/conf.c
c2cdce
@@ -1970,7 +1970,9 @@ int _snd_config_load_with_include(snd_config_t *config, snd_input_t *in,
c2cdce
 		SNDERR("%s:%d:%d:%s", fd->name ? fd->name : "_toplevel_", fd->line, fd->column, str);
c2cdce
 		goto _end;
c2cdce
 	}
c2cdce
-	if (get_char(&input) != LOCAL_UNEXPECTED_EOF) {
c2cdce
+	err = get_char(&input);
c2cdce
+	fd = input.current;
c2cdce
+	if (err != LOCAL_UNEXPECTED_EOF) {
c2cdce
 		SNDERR("%s:%d:%d:Unexpected }", fd->name ? fd->name : "", fd->line, fd->column);
c2cdce
 		err = -EINVAL;
c2cdce
 		goto _end;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 0f4821ec1729cd72a3dde3ea63f7857e92a10919 Mon Sep 17 00:00:00 2001
c2cdce
From: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Date: Sat, 26 Dec 2020 14:35:40 -0700
c2cdce
Subject: [PATCH 13/49] ucm: fix bad frees in get_list0 and get_list20
c2cdce
c2cdce
Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 src/ucm/main.c | 4 ++--
c2cdce
 1 file changed, 2 insertions(+), 2 deletions(-)
c2cdce
c2cdce
diff --git a/src/ucm/main.c b/src/ucm/main.c
c2cdce
index 3871d5aa..754b967e 100644
c2cdce
--- a/src/ucm/main.c
c2cdce
+++ b/src/ucm/main.c
c2cdce
@@ -666,7 +666,7 @@ static int get_list0(struct list_head *list,
c2cdce
 	}
c2cdce
 	return cnt;
c2cdce
       __fail:
c2cdce
-        snd_use_case_free_list((const char **)res, cnt);
c2cdce
+        snd_use_case_free_list(*result, cnt);
c2cdce
         return -ENOMEM;
c2cdce
 }
c2cdce
 
c2cdce
@@ -724,7 +724,7 @@ static int get_list20(struct list_head *list,
c2cdce
 	}
c2cdce
 	return cnt;
c2cdce
       __fail:
c2cdce
-        snd_use_case_free_list((const char **)res, cnt);
c2cdce
+        snd_use_case_free_list(*result, cnt);
c2cdce
         return -ENOMEM;
c2cdce
 }
c2cdce
 
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From c56278cfda55b9f5d106890c7354176dba8c8f4d Mon Sep 17 00:00:00 2001
c2cdce
From: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Date: Sat, 26 Dec 2020 14:35:41 -0700
c2cdce
Subject: [PATCH 14/49] rawmidi: fix memory leak in snd_rawmidi_virtual_open
c2cdce
c2cdce
Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 src/rawmidi/rawmidi_virt.c | 3 ++-
c2cdce
 1 file changed, 2 insertions(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/rawmidi/rawmidi_virt.c b/src/rawmidi/rawmidi_virt.c
c2cdce
index 2c4c27f5..884b8ff8 100644
c2cdce
--- a/src/rawmidi/rawmidi_virt.c
c2cdce
+++ b/src/rawmidi/rawmidi_virt.c
c2cdce
@@ -315,7 +315,7 @@ int snd_rawmidi_virtual_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
c2cdce
 			     int merge, int mode)
c2cdce
 {
c2cdce
 	int err;
c2cdce
-	snd_rawmidi_t *rmidi;
c2cdce
+	snd_rawmidi_t *rmidi = NULL;
c2cdce
 	snd_rawmidi_virtual_t *virt = NULL;
c2cdce
 	struct pollfd pfd;
c2cdce
 
c2cdce
@@ -392,6 +392,7 @@ int snd_rawmidi_virtual_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
c2cdce
 		free(*inputp);
c2cdce
 	if (outputp)
c2cdce
 		free(*outputp);
c2cdce
+	free(rmidi);
c2cdce
 	return err;
c2cdce
 }
c2cdce
 
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From aa28847248f2f416d9ecc6cbfa75192455400f6f Mon Sep 17 00:00:00 2001
c2cdce
From: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Date: Sat, 26 Dec 2020 14:35:43 -0700
c2cdce
Subject: [PATCH 15/49] timer: fix sizeof operator mismatch in
c2cdce
 snd_timer_query_hw_open
c2cdce
c2cdce
Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 src/timer/timer_query_hw.c | 2 +-
c2cdce
 1 file changed, 1 insertion(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/timer/timer_query_hw.c b/src/timer/timer_query_hw.c
c2cdce
index dad228c8..d8bac6e7 100644
c2cdce
--- a/src/timer/timer_query_hw.c
c2cdce
+++ b/src/timer/timer_query_hw.c
c2cdce
@@ -104,7 +104,7 @@ int snd_timer_query_hw_open(snd_timer_query_t **handle, const char *name, int mo
c2cdce
 		close(fd);
c2cdce
 		return -SND_ERROR_INCOMPATIBLE_VERSION;
c2cdce
 	}
c2cdce
-	tmr = (snd_timer_query_t *) calloc(1, sizeof(snd_timer_t));
c2cdce
+	tmr = (snd_timer_query_t *) calloc(1, sizeof(snd_timer_query_t));
c2cdce
 	if (tmr == NULL) {
c2cdce
 		close(fd);
c2cdce
 		return -ENOMEM;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 2e470d59d84a563a9efa81572ddc48d9858ceb92 Mon Sep 17 00:00:00 2001
c2cdce
From: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Date: Sat, 26 Dec 2020 14:35:44 -0700
c2cdce
Subject: [PATCH 16/49] pcm: remove dead assignments from
c2cdce
 snd_pcm_rate_(commit_area|grab_next_period)
c2cdce
c2cdce
Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 src/pcm/pcm_rate.c | 2 --
c2cdce
 1 file changed, 2 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
c2cdce
index 5bf7dbb9..dc38e95e 100644
c2cdce
--- a/src/pcm/pcm_rate.c
c2cdce
+++ b/src/pcm/pcm_rate.c
c2cdce
@@ -746,7 +746,6 @@ static int snd_pcm_rate_commit_area(snd_pcm_t *pcm, snd_pcm_rate_t *rate,
c2cdce
 		if (result < 0)
c2cdce
 			return result;
c2cdce
 	      __partial:
c2cdce
-		xfer = 0;
c2cdce
 		cont = slave_frames;
c2cdce
 		if (cont > slave_size)
c2cdce
 			cont = slave_size;
c2cdce
@@ -846,7 +845,6 @@ static int snd_pcm_rate_grab_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t hw_of
c2cdce
 		if (result < 0)
c2cdce
 			return result;
c2cdce
 	      __partial:
c2cdce
-		xfer = 0;
c2cdce
 		cont = slave_frames;
c2cdce
 		if (cont > rate->gen.slave->period_size)
c2cdce
 			cont = rate->gen.slave->period_size;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From fc719bfe4e97bbfce899cc7e67df08ecd573c5d3 Mon Sep 17 00:00:00 2001
c2cdce
From: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Date: Sat, 26 Dec 2020 14:35:45 -0700
c2cdce
Subject: [PATCH 17/49] pcm_multi: remove dead assignment from
c2cdce
 _snd_pcm_multi_open
c2cdce
c2cdce
Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 src/pcm/pcm_multi.c | 1 -
c2cdce
 1 file changed, 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c
c2cdce
index 53c414d5..5fa09b9b 100644
c2cdce
--- a/src/pcm/pcm_multi.c
c2cdce
+++ b/src/pcm/pcm_multi.c
c2cdce
@@ -1323,7 +1323,6 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
c2cdce
 		err = -ENOMEM;
c2cdce
 		goto _free;
c2cdce
 	}
c2cdce
-	idx = 0;
c2cdce
 	for (idx = 0; idx < channels_count; ++idx)
c2cdce
 		channels_sidx[idx] = -1;
c2cdce
 	idx = 0;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 9ebd29d2d31df0f8967f3e60cf24bb63c95d4984 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Sun, 27 Dec 2020 13:17:26 +0100
c2cdce
Subject: [PATCH 18/49] conf: fix get_hexachar() return value
c2cdce
c2cdce
Reported-by: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/conf.c | 2 +-
c2cdce
 1 file changed, 1 insertion(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/conf.c b/src/conf.c
c2cdce
index 44d1bfde..6cfe65bf 100644
c2cdce
--- a/src/conf.c
c2cdce
+++ b/src/conf.c
c2cdce
@@ -887,7 +887,7 @@ static inline int get_hexachar(input_t *input)
c2cdce
 	if (c >= '0' && c <= '9') num |= (c - '0') << 0;
c2cdce
 	else if (c >= 'a' && c <= 'f') num |= (c - 'a') << 0;
c2cdce
 	else if (c >= 'A' && c <= 'F') num |= (c - 'A') << 0;
c2cdce
-	return c;
c2cdce
+	return num;
c2cdce
 }
c2cdce
 
c2cdce
 static int get_quotedchar(input_t *input)
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 36aff79747b23b9535e81befe8b7b2972837bce3 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Sun, 27 Dec 2020 13:29:33 +0100
c2cdce
Subject: [PATCH 19/49] pcm: fix __snd_pcm_state() return value
c2cdce
c2cdce
The __snd_pcm_state() must return a valid state, not an error value
c2cdce
when the plugin callback is not defined. Use the first state
c2cdce
SND_PCM_STATE_OPEN - the other functions will return the error
c2cdce
code depending on this state.
c2cdce
c2cdce
Link: https://lore.kernel.org/alsa-devel/20201226213547.175071-10-alexhenrie24@gmail.com/
c2cdce
Reported-by: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_local.h | 2 +-
c2cdce
 1 file changed, 1 insertion(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
c2cdce
index fe77e50d..bec5a408 100644
c2cdce
--- a/src/pcm/pcm_local.h
c2cdce
+++ b/src/pcm/pcm_local.h
c2cdce
@@ -444,7 +444,7 @@ static inline int __snd_pcm_start(snd_pcm_t *pcm)
c2cdce
 static inline snd_pcm_state_t __snd_pcm_state(snd_pcm_t *pcm)
c2cdce
 {
c2cdce
 	if (!pcm->fast_ops->state)
c2cdce
-		return -ENOSYS;
c2cdce
+		return SND_PCM_STATE_OPEN;
c2cdce
 	return pcm->fast_ops->state(pcm->fast_op_arg);
c2cdce
 }
c2cdce
 
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From a92ad2fea4b36d7282f4a571275fb492dd1bba75 Mon Sep 17 00:00:00 2001
c2cdce
From: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Date: Sun, 27 Dec 2020 18:43:15 -0700
c2cdce
Subject: [PATCH 20/49] confmisc: fix memory leak in snd_func_concat
c2cdce
c2cdce
Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
---
c2cdce
 src/confmisc.c | 3 +--
c2cdce
 1 file changed, 1 insertion(+), 2 deletions(-)
c2cdce
c2cdce
diff --git a/src/confmisc.c b/src/confmisc.c
c2cdce
index eb8218c1..3ce95c7a 100644
c2cdce
--- a/src/confmisc.c
c2cdce
+++ b/src/confmisc.c
c2cdce
@@ -419,7 +419,6 @@ int snd_func_concat(snd_config_t **dst, snd_config_t *root, snd_config_t *src,
c2cdce
 				tmp = realloc(res, len + len1 + 1);
c2cdce
 				if (tmp == NULL) {
c2cdce
 					free(ptr);
c2cdce
-					free(res);
c2cdce
 					err = -ENOMEM;
c2cdce
 					goto __error;
c2cdce
 				}
c2cdce
@@ -440,8 +439,8 @@ int snd_func_concat(snd_config_t **dst, snd_config_t *root, snd_config_t *src,
c2cdce
 	err = snd_config_get_id(src, &id;;
c2cdce
 	if (err >= 0)
c2cdce
 		err = snd_config_imake_string(dst, id, res);
c2cdce
-	free(res);
c2cdce
       __error:
c2cdce
+	free(res);
c2cdce
 	return err;
c2cdce
 }
c2cdce
 #ifndef DOC_HIDDEN
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 6c24cd2e60cc9c1fca809ffeeb7ffe8af94b201e Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Tue, 29 Dec 2020 11:15:46 +0100
c2cdce
Subject: [PATCH 21/49] conf: fix return code in _snd_config_load_with_include
c2cdce
c2cdce
Fixes: 5275d170e0 ("conf: fix use after free in _snd_config_load_with_include")
c2cdce
BugLink: https://github.com/alsa-project/alsa-lib/issues/108
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/conf.c | 1 +
c2cdce
 1 file changed, 1 insertion(+)
c2cdce
c2cdce
diff --git a/src/conf.c b/src/conf.c
c2cdce
index 6cfe65bf..3c943db2 100644
c2cdce
--- a/src/conf.c
c2cdce
+++ b/src/conf.c
c2cdce
@@ -1977,6 +1977,7 @@ int _snd_config_load_with_include(snd_config_t *config, snd_input_t *in,
c2cdce
 		err = -EINVAL;
c2cdce
 		goto _end;
c2cdce
 	}
c2cdce
+	err = 0;
c2cdce
  _end:
c2cdce
 	while (fd->next) {
c2cdce
 		fd_next = fd->next;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From afe6ff3b33ee6e5ea3511fe458bfd4e516b10bcf Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Wed, 30 Dec 2020 09:31:10 +0100
c2cdce
Subject: [PATCH 22/49] pcm: plugin status - fix the return value (regression)
c2cdce
c2cdce
The snd_pcm_plugin_avail_update() error code in snd_pcm_plugin_status()
c2cdce
should not be reported to the caller. The state errors can be determined
c2cdce
using the state member in the status structure.
c2cdce
c2cdce
Fixes: 4f90392f07e ("pcm: fix the snd_pcm_plugin_status() avail and delay fields")
c2cdce
BugLink: https://github.com/alsa-project/alsa-lib/issues/107
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_plugin.c | 8 +++-----
c2cdce
 1 file changed, 3 insertions(+), 5 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
c2cdce
index 5739cfc2..76a524fa 100644
c2cdce
--- a/src/pcm/pcm_plugin.c
c2cdce
+++ b/src/pcm/pcm_plugin.c
c2cdce
@@ -541,19 +541,17 @@ static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
c2cdce
 static int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 {
c2cdce
 	snd_pcm_plugin_t *plugin = pcm->private_data;
c2cdce
-	snd_pcm_sframes_t err, avail;
c2cdce
+	snd_pcm_sframes_t err;
c2cdce
 
c2cdce
 	/* sync with the latest hw and appl ptrs */
c2cdce
-	avail = snd_pcm_plugin_avail_update(pcm);
c2cdce
-	if (avail < 0)
c2cdce
-		return avail;
c2cdce
+	snd_pcm_plugin_avail_update(pcm);
c2cdce
 
c2cdce
 	err = snd_pcm_status(plugin->gen.slave, status);
c2cdce
 	if (err < 0)
c2cdce
 		return err;
c2cdce
 	status->appl_ptr = *pcm->appl.ptr;
c2cdce
 	status->hw_ptr = *pcm->hw.ptr;
c2cdce
-	status->avail = avail;
c2cdce
+	status->avail = snd_pcm_mmap_avail(pcm);
c2cdce
 	status->delay = snd_pcm_mmap_delay(pcm);
c2cdce
 	return 0;
c2cdce
 }
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 49eea5d7bc7d39f9a4cc1f3b3a813e90b90519eb Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Sun, 3 Jan 2021 16:16:10 +0100
c2cdce
Subject: [PATCH 23/49] pcm: plugin status - revert the recent changes
c2cdce
c2cdce
It's no reason to sync the avail/delay fields using the mirrored
c2cdce
buffer pointers. The slave information must be valid.
c2cdce
c2cdce
The original report probably tries to fix something for
c2cdce
the specific plugin. Revert all changes.
c2cdce
c2cdce
Fixes: afe6ff3b33e ("pcm: plugin status - fix the return value (regression)")
c2cdce
Fixes: 4f90392f07e ("pcm: fix the snd_pcm_plugin_status() avail and delay fields")
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_plugin.c | 2 --
c2cdce
 1 file changed, 2 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
c2cdce
index 76a524fa..ea60eb98 100644
c2cdce
--- a/src/pcm/pcm_plugin.c
c2cdce
+++ b/src/pcm/pcm_plugin.c
c2cdce
@@ -551,8 +551,6 @@ static int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 		return err;
c2cdce
 	status->appl_ptr = *pcm->appl.ptr;
c2cdce
 	status->hw_ptr = *pcm->hw.ptr;
c2cdce
-	status->avail = snd_pcm_mmap_avail(pcm);
c2cdce
-	status->delay = snd_pcm_mmap_delay(pcm);
c2cdce
 	return 0;
c2cdce
 }
c2cdce
 
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From fa1895aa2b4f3f154e537bee92860fe793045643 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Sun, 3 Jan 2021 16:34:04 +0100
c2cdce
Subject: [PATCH 24/49] pcm: plugin - tidy snd_pcm_plugin_avail_update()
c2cdce
c2cdce
No functional changes - move the code to snd_pcm_plugin_sync_hw_ptr()
c2cdce
and put the mmap capture updates to separate function for readability.
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_plugin.c | 142 +++++++++++++++++++++++--------------------
c2cdce
 1 file changed, 76 insertions(+), 66 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
c2cdce
index ea60eb98..83793397 100644
c2cdce
--- a/src/pcm/pcm_plugin.c
c2cdce
+++ b/src/pcm/pcm_plugin.c
c2cdce
@@ -460,82 +460,92 @@ snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
c2cdce
 	return xfer > 0 ? xfer : err;
c2cdce
 }
c2cdce
 
c2cdce
-static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
c2cdce
+static snd_pcm_sframes_t
c2cdce
+snd_pcm_plugin_sync_hw_ptr_capture(snd_pcm_t *pcm,
c2cdce
+				   snd_pcm_sframes_t slave_size)
c2cdce
 {
c2cdce
 	snd_pcm_plugin_t *plugin = pcm->private_data;
c2cdce
 	snd_pcm_t *slave = plugin->gen.slave;
c2cdce
-	snd_pcm_sframes_t slave_size;
c2cdce
+	const snd_pcm_channel_area_t *areas;
c2cdce
+	snd_pcm_uframes_t xfer, hw_offset, size;
c2cdce
 	int err;
c2cdce
 
c2cdce
-	slave_size = snd_pcm_avail_update(slave);
c2cdce
+	xfer = snd_pcm_mmap_capture_avail(pcm);
c2cdce
+	size = pcm->buffer_size - xfer;
c2cdce
+	areas = snd_pcm_mmap_areas(pcm);
c2cdce
+	hw_offset = snd_pcm_mmap_hw_offset(pcm);
c2cdce
+	while (size > 0 && slave_size > 0) {
c2cdce
+		snd_pcm_uframes_t frames = size;
c2cdce
+		snd_pcm_uframes_t cont = pcm->buffer_size - hw_offset;
c2cdce
+		const snd_pcm_channel_area_t *slave_areas;
c2cdce
+		snd_pcm_uframes_t slave_offset;
c2cdce
+		snd_pcm_uframes_t slave_frames = ULONG_MAX;
c2cdce
+		snd_pcm_sframes_t result;
c2cdce
+		/* As mentioned in the ALSA API (see pcm/pcm.c:942):
c2cdce
+		 * The function #snd_pcm_avail_update()
c2cdce
+		 * have to be called before any mmap begin+commit operation.
c2cdce
+		 * Otherwise the snd_pcm_areas_copy will not called a second time.
c2cdce
+		 * But this is needed, if the ring buffer wrap is reached and
c2cdce
+		 * there is more data available.
c2cdce
+		 */
c2cdce
+		slave_size = snd_pcm_avail_update(slave);
c2cdce
+		result = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
c2cdce
+		if (result < 0) {
c2cdce
+			err = result;
c2cdce
+			goto error;
c2cdce
+		}
c2cdce
+		if (frames > cont)
c2cdce
+			frames = cont;
c2cdce
+		frames = (plugin->read)(pcm, areas, hw_offset, frames,
c2cdce
+					slave_areas, slave_offset, &slave_frames);
c2cdce
+		result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
c2cdce
+		if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
c2cdce
+			snd_pcm_sframes_t res;
c2cdce
+			res = plugin->undo_read(slave, areas, hw_offset, frames, slave_frames - result);
c2cdce
+			if (res < 0) {
c2cdce
+				err = res;
c2cdce
+				goto error;
c2cdce
+			}
c2cdce
+			frames -= res;
c2cdce
+		}
c2cdce
+		if (result <= 0) {
c2cdce
+			err = result;
c2cdce
+			goto error;
c2cdce
+		}
c2cdce
+		snd_pcm_mmap_hw_forward(pcm, frames);
c2cdce
+		if (frames == cont)
c2cdce
+			hw_offset = 0;
c2cdce
+		else
c2cdce
+			hw_offset += frames;
c2cdce
+		size -= frames;
c2cdce
+		slave_size -= slave_frames;
c2cdce
+		xfer += frames;
c2cdce
+	}
c2cdce
+	return (snd_pcm_sframes_t)xfer;
c2cdce
+error:
c2cdce
+	return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
c2cdce
+}
c2cdce
+
c2cdce
+static snd_pcm_sframes_t snd_pcm_plugin_sync_hw_ptr(snd_pcm_t *pcm,
c2cdce
+						    snd_pcm_uframes_t slave_hw_ptr,
c2cdce
+						    snd_pcm_sframes_t slave_size)
c2cdce
+{
c2cdce
 	if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
c2cdce
 	    pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED &&
c2cdce
 	    pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED)
c2cdce
-		goto _capture;
c2cdce
-        *pcm->hw.ptr = *slave->hw.ptr;
c2cdce
+		return snd_pcm_plugin_sync_hw_ptr_capture(pcm, slave_size);
c2cdce
+        *pcm->hw.ptr = slave_hw_ptr;
c2cdce
         return slave_size;
c2cdce
- _capture:
c2cdce
- 	{
c2cdce
-		const snd_pcm_channel_area_t *areas;
c2cdce
-		snd_pcm_uframes_t xfer, hw_offset, size;
c2cdce
-		
c2cdce
-		xfer = snd_pcm_mmap_capture_avail(pcm);
c2cdce
-		size = pcm->buffer_size - xfer;
c2cdce
-		areas = snd_pcm_mmap_areas(pcm);
c2cdce
-		hw_offset = snd_pcm_mmap_hw_offset(pcm);
c2cdce
-		while (size > 0 && slave_size > 0) {
c2cdce
-			snd_pcm_uframes_t frames = size;
c2cdce
-			snd_pcm_uframes_t cont = pcm->buffer_size - hw_offset;
c2cdce
-			const snd_pcm_channel_area_t *slave_areas;
c2cdce
-			snd_pcm_uframes_t slave_offset;
c2cdce
-			snd_pcm_uframes_t slave_frames = ULONG_MAX;
c2cdce
-			snd_pcm_sframes_t result;
c2cdce
-			/* As mentioned in the ALSA API (see pcm/pcm.c:942):
c2cdce
-			 * The function #snd_pcm_avail_update()
c2cdce
-			 * have to be called before any mmap begin+commit operation.
c2cdce
-			 * Otherwise the snd_pcm_areas_copy will not called a second time.
c2cdce
-			 * But this is needed, if the ring buffer wrap is reached and
c2cdce
-			 * there is more data available.
c2cdce
-			 */
c2cdce
-			slave_size = snd_pcm_avail_update(slave);
c2cdce
-			result = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
c2cdce
-			if (result < 0) {
c2cdce
-				err = result;
c2cdce
-				goto error;
c2cdce
-			}
c2cdce
-			if (frames > cont)
c2cdce
-				frames = cont;
c2cdce
-			frames = (plugin->read)(pcm, areas, hw_offset, frames,
c2cdce
-					      slave_areas, slave_offset, &slave_frames);
c2cdce
-			result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
c2cdce
-			if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
c2cdce
-				snd_pcm_sframes_t res;
c2cdce
-				
c2cdce
-				res = plugin->undo_read(slave, areas, hw_offset, frames, slave_frames - result);
c2cdce
-				if (res < 0) {
c2cdce
-					err = res;
c2cdce
-					goto error;
c2cdce
-				}
c2cdce
-				frames -= res;
c2cdce
-			}
c2cdce
-			if (result <= 0) {
c2cdce
-				err = result;
c2cdce
-				goto error;
c2cdce
-			}
c2cdce
-			snd_pcm_mmap_hw_forward(pcm, frames);
c2cdce
-			if (frames == cont)
c2cdce
-				hw_offset = 0;
c2cdce
-			else
c2cdce
-				hw_offset += frames;
c2cdce
-			size -= frames;
c2cdce
-			slave_size -= slave_frames;
c2cdce
-			xfer += frames;
c2cdce
-		}
c2cdce
-		return (snd_pcm_sframes_t)xfer;
c2cdce
+}
c2cdce
 
c2cdce
-	error:
c2cdce
-		return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
c2cdce
-	}
c2cdce
+static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
c2cdce
+{
c2cdce
+	snd_pcm_plugin_t *plugin = pcm->private_data;
c2cdce
+	snd_pcm_t *slave = plugin->gen.slave;
c2cdce
+	snd_pcm_sframes_t slave_size;
c2cdce
+
c2cdce
+	slave_size = snd_pcm_avail_update(slave);
c2cdce
+	return snd_pcm_plugin_sync_hw_ptr(pcm, *slave->hw.ptr, slave_size);
c2cdce
 }
c2cdce
 
c2cdce
 static int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 28cc099d9ea3962b033cb1cb9c3e07db828d9ff7 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Sun, 3 Jan 2021 16:41:29 +0100
c2cdce
Subject: [PATCH 25/49] pcm: plugin - optimize sync in snd_pcm_plugin_status()
c2cdce
c2cdce
Do hw_ptr sync only once after the status call. This avoids
c2cdce
double update.
c2cdce
c2cdce
Also, the application pointer must not change when
c2cdce
the status is called. Add assert() call for this condition.
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_plugin.c | 7 ++-----
c2cdce
 1 file changed, 2 insertions(+), 5 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
c2cdce
index 83793397..6a815145 100644
c2cdce
--- a/src/pcm/pcm_plugin.c
c2cdce
+++ b/src/pcm/pcm_plugin.c
c2cdce
@@ -553,14 +553,11 @@ static int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 	snd_pcm_plugin_t *plugin = pcm->private_data;
c2cdce
 	snd_pcm_sframes_t err;
c2cdce
 
c2cdce
-	/* sync with the latest hw and appl ptrs */
c2cdce
-	snd_pcm_plugin_avail_update(pcm);
c2cdce
-
c2cdce
 	err = snd_pcm_status(plugin->gen.slave, status);
c2cdce
 	if (err < 0)
c2cdce
 		return err;
c2cdce
-	status->appl_ptr = *pcm->appl.ptr;
c2cdce
-	status->hw_ptr = *pcm->hw.ptr;
c2cdce
+	assert(status->appl_ptr == *pcm->appl.ptr);
c2cdce
+	snd_pcm_plugin_sync_hw_ptr(pcm, status->hw_ptr, status->avail);
c2cdce
 	return 0;
c2cdce
 }
c2cdce
 
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 21549e6583f1dfe5b2fe1aaa88345e4645dd96d0 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Wed, 30 Dec 2020 17:49:33 +0100
c2cdce
Subject: [PATCH 26/49] Revert "pcm_plugin: fix delay"
c2cdce
c2cdce
This reverts commit aba87e509898ec9ddb3e319267d7c267409ff100.
c2cdce
c2cdce
The commit does not look good. The plugins must handle
c2cdce
the delay value correctly.
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_plugin.c | 6 ------
c2cdce
 1 file changed, 6 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
c2cdce
index 6a815145..5787a43d 100644
c2cdce
--- a/src/pcm/pcm_plugin.c
c2cdce
+++ b/src/pcm/pcm_plugin.c
c2cdce
@@ -142,12 +142,6 @@ static int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
c2cdce
 	int err = snd_pcm_delay(plugin->gen.slave, &sd);
c2cdce
 	if (err < 0)
c2cdce
 		return err;
c2cdce
-        if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
c2cdce
-	    pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED &&
c2cdce
-	    pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
c2cdce
-                sd += snd_pcm_mmap_capture_avail(pcm);
c2cdce
-        }        
c2cdce
-
c2cdce
 	*delayp = sd;
c2cdce
 	return 0;
c2cdce
 }
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 6ca01c07ee13435d6c2db4e9121d9a86cc4b1457 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Wed, 30 Dec 2020 19:14:25 +0100
c2cdce
Subject: [PATCH 27/49] pcm: ioplug - fix the delay calculation in the status
c2cdce
 callback
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_ioplug.c | 32 ++++++++++++++++++--------------
c2cdce
 1 file changed, 18 insertions(+), 14 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c
c2cdce
index 9b1b8ac3..f2315a10 100644
c2cdce
--- a/src/pcm/pcm_ioplug.c
c2cdce
+++ b/src/pcm/pcm_ioplug.c
c2cdce
@@ -107,9 +107,24 @@ static int snd_pcm_ioplug_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *i
c2cdce
 	return snd_pcm_channel_info_shm(pcm, info, -1);
c2cdce
 }
c2cdce
 
c2cdce
+static int snd_pcm_ioplug_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
c2cdce
+{
c2cdce
+	ioplug_priv_t *io = pcm->private_data;
c2cdce
+
c2cdce
+	if (io->data->version >= 0x010001 &&
c2cdce
+	    io->data->callback->delay)
c2cdce
+		return io->data->callback->delay(io->data, delayp);
c2cdce
+	else {
c2cdce
+		snd_pcm_ioplug_hw_ptr_update(pcm);
c2cdce
+		*delayp = snd_pcm_mmap_hw_avail(pcm);
c2cdce
+	}
c2cdce
+	return 0;
c2cdce
+}
c2cdce
+
c2cdce
 static int snd_pcm_ioplug_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 {
c2cdce
 	ioplug_priv_t *io = pcm->private_data;
c2cdce
+	snd_pcm_sframes_t sd;
c2cdce
 
c2cdce
 	memset(status, 0, sizeof(*status));
c2cdce
 	snd_pcm_ioplug_hw_ptr_update(pcm);
c2cdce
@@ -118,6 +133,9 @@ static int snd_pcm_ioplug_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 	gettimestamp(&status->tstamp, pcm->tstamp_type);
c2cdce
 	status->avail = snd_pcm_mmap_avail(pcm);
c2cdce
 	status->avail_max = io->avail_max;
c2cdce
+	if (snd_pcm_ioplug_delay(pcm, &sd) < 0)
c2cdce
+		sd = snd_pcm_mmap_delay(pcm);
c2cdce
+	status->delay = sd;
c2cdce
 	return 0;
c2cdce
 }
c2cdce
 
c2cdce
@@ -133,20 +151,6 @@ static int snd_pcm_ioplug_hwsync(snd_pcm_t *pcm)
c2cdce
 	return 0;
c2cdce
 }
c2cdce
 
c2cdce
-static int snd_pcm_ioplug_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
c2cdce
-{
c2cdce
-	ioplug_priv_t *io = pcm->private_data;
c2cdce
-
c2cdce
-	if (io->data->version >= 0x010001 &&
c2cdce
-	    io->data->callback->delay)
c2cdce
-		return io->data->callback->delay(io->data, delayp);
c2cdce
-	else {
c2cdce
-		snd_pcm_ioplug_hw_ptr_update(pcm);
c2cdce
-		*delayp = snd_pcm_mmap_hw_avail(pcm);
c2cdce
-	}
c2cdce
-	return 0;
c2cdce
-}
c2cdce
-
c2cdce
 static int snd_pcm_ioplug_reset(snd_pcm_t *pcm)
c2cdce
 {
c2cdce
 	ioplug_priv_t *io = pcm->private_data;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 5988bb3ff42827ab4c13f248291ad1767c8d973d Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Sun, 3 Jan 2021 16:56:38 +0100
c2cdce
Subject: [PATCH 28/49] pcm: rate - tidy up snd_pcm_rate_avail_update()
c2cdce
c2cdce
No functional change - just move the capture code to
c2cdce
a separate function for the better readability.
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_rate.c | 37 +++++++++++++++++++++----------------
c2cdce
 1 file changed, 21 insertions(+), 16 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
c2cdce
index dc38e95e..7073f8ab 100644
c2cdce
--- a/src/pcm/pcm_rate.c
c2cdce
+++ b/src/pcm/pcm_rate.c
c2cdce
@@ -964,29 +964,18 @@ static snd_pcm_sframes_t snd_pcm_rate_mmap_commit(snd_pcm_t *pcm,
c2cdce
 	return size;
c2cdce
 }
c2cdce
 
c2cdce
-static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm)
c2cdce
+static snd_pcm_sframes_t snd_pcm_rate_avail_update_capture(snd_pcm_t *pcm,
c2cdce
+							   snd_pcm_sframes_t slave_size)
c2cdce
 {
c2cdce
 	snd_pcm_rate_t *rate = pcm->private_data;
c2cdce
 	snd_pcm_t *slave = rate->gen.slave;
c2cdce
-	snd_pcm_sframes_t slave_size;
c2cdce
-
c2cdce
-	slave_size = snd_pcm_avail_update(slave);
c2cdce
-	if (slave_size < 0)
c2cdce
-		return slave_size;
c2cdce
-
c2cdce
-	if (pcm->stream == SND_PCM_STREAM_CAPTURE)
c2cdce
-		goto _capture;
c2cdce
-	snd_pcm_rate_sync_hwptr(pcm);
c2cdce
-	snd_pcm_rate_sync_playback_area(pcm, rate->appl_ptr);
c2cdce
-	return snd_pcm_mmap_avail(pcm);
c2cdce
- _capture: {
c2cdce
 	snd_pcm_uframes_t xfer, hw_offset, size;
c2cdce
 	
c2cdce
 	xfer = snd_pcm_mmap_capture_avail(pcm);
c2cdce
 	size = pcm->buffer_size - xfer;
c2cdce
 	hw_offset = snd_pcm_mmap_hw_offset(pcm);
c2cdce
 	while (size >= pcm->period_size &&
c2cdce
-	       (snd_pcm_uframes_t)slave_size >= rate->gen.slave->period_size) {
c2cdce
+	       (snd_pcm_uframes_t)slave_size >= slave->period_size) {
c2cdce
 		int err = snd_pcm_rate_grab_next_period(pcm, hw_offset);
c2cdce
 		if (err < 0)
c2cdce
 			return err;
c2cdce
@@ -994,13 +983,29 @@ static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm)
c2cdce
 			return (snd_pcm_sframes_t)xfer;
c2cdce
 		xfer += pcm->period_size;
c2cdce
 		size -= pcm->period_size;
c2cdce
-		slave_size -= rate->gen.slave->period_size;
c2cdce
+		slave_size -= slave->period_size;
c2cdce
 		hw_offset += pcm->period_size;
c2cdce
 		hw_offset %= pcm->buffer_size;
c2cdce
 		snd_pcm_mmap_hw_forward(pcm, pcm->period_size);
c2cdce
 	}
c2cdce
 	return (snd_pcm_sframes_t)xfer;
c2cdce
- }
c2cdce
+}
c2cdce
+
c2cdce
+static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm)
c2cdce
+{
c2cdce
+	snd_pcm_rate_t *rate = pcm->private_data;
c2cdce
+	snd_pcm_sframes_t slave_size;
c2cdce
+
c2cdce
+	slave_size = snd_pcm_avail_update(rate->gen.slave);
c2cdce
+	if (slave_size < 0)
c2cdce
+		return slave_size;
c2cdce
+
c2cdce
+	if (pcm->stream == SND_PCM_STREAM_CAPTURE)
c2cdce
+		return snd_pcm_rate_avail_update_capture(pcm, slave_size);
c2cdce
+
c2cdce
+	snd_pcm_rate_sync_hwptr(pcm);
c2cdce
+	snd_pcm_rate_sync_playback_area(pcm, rate->appl_ptr);
c2cdce
+	return snd_pcm_mmap_avail(pcm);
c2cdce
 }
c2cdce
 
c2cdce
 static int snd_pcm_rate_htimestamp(snd_pcm_t *pcm,
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 6cee452eabc5cfdf0a6955033b8ac8f6e12ea883 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Sun, 3 Jan 2021 17:13:50 +0100
c2cdce
Subject: [PATCH 29/49] pcm: ioplug - fix the delay calculation for old plugins
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_ioplug.c | 2 +-
c2cdce
 1 file changed, 1 insertion(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c
c2cdce
index f2315a10..e141b1f9 100644
c2cdce
--- a/src/pcm/pcm_ioplug.c
c2cdce
+++ b/src/pcm/pcm_ioplug.c
c2cdce
@@ -116,7 +116,7 @@ static int snd_pcm_ioplug_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
c2cdce
 		return io->data->callback->delay(io->data, delayp);
c2cdce
 	else {
c2cdce
 		snd_pcm_ioplug_hw_ptr_update(pcm);
c2cdce
-		*delayp = snd_pcm_mmap_hw_avail(pcm);
c2cdce
+		*delayp = snd_pcm_mmap_delay(pcm);
c2cdce
 	}
c2cdce
 	return 0;
c2cdce
 }
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From fc0f7af9ee7bd4c31c2bab229e8e79eb96e908fa Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Mon, 4 Jan 2021 12:29:00 +0100
c2cdce
Subject: [PATCH 30/49] pcm: rate - use pcm_frame_diff() in
c2cdce
 snd_pcm_rate_playback_internal_delay()
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_rate.c | 6 +-----
c2cdce
 1 file changed, 1 insertion(+), 5 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
c2cdce
index 7073f8ab..abb2753f 100644
c2cdce
--- a/src/pcm/pcm_rate.c
c2cdce
+++ b/src/pcm/pcm_rate.c
c2cdce
@@ -612,11 +612,7 @@ static snd_pcm_uframes_t snd_pcm_rate_playback_internal_delay(snd_pcm_t *pcm)
c2cdce
 {
c2cdce
 	snd_pcm_rate_t *rate = pcm->private_data;
c2cdce
 
c2cdce
-	if (rate->appl_ptr < rate->last_commit_ptr) {
c2cdce
-		return rate->appl_ptr - rate->last_commit_ptr + pcm->boundary;
c2cdce
-	} else {
c2cdce
-		return rate->appl_ptr - rate->last_commit_ptr;
c2cdce
-	}
c2cdce
+	return pcm_frame_diff(rate->appl_ptr, rate->last_commit_ptr, pcm->boundary);
c2cdce
 }
c2cdce
 
c2cdce
 static int snd_pcm_rate_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From da5b70d3fae091a8568b80a476c1cf340965805a Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Mon, 4 Jan 2021 12:32:25 +0100
c2cdce
Subject: [PATCH 31/49] pcm: plugin - fix status code for capture
c2cdce
c2cdce
The recent updates do not take in account the possible
c2cdce
calls for the capture stream. Fix the avail and delay
c2cdce
inconsistencies (and assert).
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_plugin.c | 21 +++++++++++++++++++--
c2cdce
 1 file changed, 19 insertions(+), 2 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
c2cdce
index 5787a43d..7ed6f25a 100644
c2cdce
--- a/src/pcm/pcm_plugin.c
c2cdce
+++ b/src/pcm/pcm_plugin.c
c2cdce
@@ -545,13 +545,30 @@ static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
c2cdce
 static int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 {
c2cdce
 	snd_pcm_plugin_t *plugin = pcm->private_data;
c2cdce
-	snd_pcm_sframes_t err;
c2cdce
+	snd_pcm_sframes_t err, diff;
c2cdce
 
c2cdce
 	err = snd_pcm_status(plugin->gen.slave, status);
c2cdce
 	if (err < 0)
c2cdce
 		return err;
c2cdce
-	assert(status->appl_ptr == *pcm->appl.ptr);
c2cdce
 	snd_pcm_plugin_sync_hw_ptr(pcm, status->hw_ptr, status->avail);
c2cdce
+	/*
c2cdce
+	 * For capture stream, the situation is more complicated, because
c2cdce
+	 * snd_pcm_plugin_avail_update() commits the data to the slave pcm.
c2cdce
+	 * It means that the slave appl_ptr is updated. Calculate diff and
c2cdce
+	 * update the delay and avail.
c2cdce
+	 *
c2cdce
+	 * This resolves the data inconsistency for immediate calls:
c2cdce
+	 *    snd_pcm_avail_update()
c2cdce
+	 *    snd_pcm_status()
c2cdce
+	 */
c2cdce
+	if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
c2cdce
+		status->appl_ptr = *pcm->appl.ptr;
c2cdce
+		diff = pcm_frame_diff(status->appl_ptr, *pcm->appl.ptr, pcm->boundary);
c2cdce
+		status->avail += diff;
c2cdce
+		status->delay += diff;
c2cdce
+	} else {
c2cdce
+		assert(status->appl_ptr == *pcm->appl.ptr);
c2cdce
+	}
c2cdce
 	return 0;
c2cdce
 }
c2cdce
 
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From ac520b2ed11f31e789a4da1d55e360e3eaeac50d Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Mon, 4 Jan 2021 17:14:42 +0100
c2cdce
Subject: [PATCH 32/49] pcm: rate - use pcm_frame_diff() on related places
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_rate.c | 20 +++++++-------------
c2cdce
 1 file changed, 7 insertions(+), 13 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
c2cdce
index abb2753f..3d301d0e 100644
c2cdce
--- a/src/pcm/pcm_rate.c
c2cdce
+++ b/src/pcm/pcm_rate.c
c2cdce
@@ -561,17 +561,16 @@ snd_pcm_rate_read_areas1(snd_pcm_t *pcm,
c2cdce
 
c2cdce
 static inline void snd_pcm_rate_sync_hwptr0(snd_pcm_t *pcm, snd_pcm_uframes_t slave_hw_ptr)
c2cdce
 {
c2cdce
-	snd_pcm_rate_t *rate = pcm->private_data;
c2cdce
-
c2cdce
-	snd_pcm_sframes_t slave_hw_ptr_diff = slave_hw_ptr - rate->last_slave_hw_ptr;
c2cdce
+	snd_pcm_rate_t *rate;
c2cdce
+	snd_pcm_sframes_t slave_hw_ptr_diff;
c2cdce
 	snd_pcm_sframes_t last_slave_hw_ptr_frac;
c2cdce
 
c2cdce
 	if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
c2cdce
 		return;
c2cdce
 
c2cdce
-	if (slave_hw_ptr_diff < 0)
c2cdce
-		slave_hw_ptr_diff += rate->gen.slave->boundary; /* slave boundary wraparound */
c2cdce
-	else if (slave_hw_ptr_diff == 0)
c2cdce
+	rate = pcm->private_data;
c2cdce
+	slave_hw_ptr_diff = pcm_frame_diff(slave_hw_ptr, rate->last_slave_hw_ptr, rate->gen.slave->boundary);
c2cdce
+	if (slave_hw_ptr_diff == 0)
c2cdce
 		return;
c2cdce
 	last_slave_hw_ptr_frac = rate->last_slave_hw_ptr % rate->gen.slave->period_size;
c2cdce
 	/* While handling fraction part fo slave period, rounded value will be
c2cdce
@@ -922,10 +921,7 @@ static int snd_pcm_rate_sync_playback_area(snd_pcm_t *pcm, snd_pcm_uframes_t app
c2cdce
 	if (slave_size < 0)
c2cdce
 		return slave_size;
c2cdce
 
c2cdce
-	if (appl_ptr < rate->last_commit_ptr)
c2cdce
-		xfer = appl_ptr - rate->last_commit_ptr + pcm->boundary;
c2cdce
-	else
c2cdce
-		xfer = appl_ptr - rate->last_commit_ptr;
c2cdce
+	xfer = pcm_frame_diff(appl_ptr, rate->last_commit_ptr, pcm->boundary);
c2cdce
 	while (xfer >= pcm->period_size &&
c2cdce
 	       (snd_pcm_uframes_t)slave_size >= rate->gen.slave->period_size) {
c2cdce
 		err = snd_pcm_rate_commit_next_period(pcm, rate->last_commit_ptr % pcm->buffer_size);
c2cdce
@@ -1059,9 +1055,7 @@ static int snd_pcm_rate_drain(snd_pcm_t *pcm)
c2cdce
 		sw_params.avail_min = 1;
c2cdce
 		snd_pcm_sw_params(rate->gen.slave, &sw_params);
c2cdce
 
c2cdce
-		size = rate->appl_ptr - rate->last_commit_ptr;
c2cdce
-		if (size > pcm->boundary)
c2cdce
-			size -= pcm->boundary;
c2cdce
+		size = pcm_frame_diff(rate->appl_ptr, rate->last_commit_ptr, pcm->boundary);
c2cdce
 		ofs = rate->last_commit_ptr % pcm->buffer_size;
c2cdce
 		while (size > 0) {
c2cdce
 			snd_pcm_uframes_t psize, spsize;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From b62f66442bfbcea7c11afe4917e196fa95a65083 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Mon, 4 Jan 2021 17:27:32 +0100
c2cdce
Subject: [PATCH 33/49] pcm: rate - fix the capture delay values
c2cdce
c2cdce
Use the correct snd_pcm_mmap_capture_delay() function instead
c2cdce
snd_pcm_mmap_capture_hw_avail().
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_rate.c | 8 ++------
c2cdce
 1 file changed, 2 insertions(+), 6 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
c2cdce
index 3d301d0e..770aafea 100644
c2cdce
--- a/src/pcm/pcm_rate.c
c2cdce
+++ b/src/pcm/pcm_rate.c
c2cdce
@@ -632,7 +632,7 @@ static int snd_pcm_rate_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
c2cdce
 				+ snd_pcm_rate_playback_internal_delay(pcm);
c2cdce
 	} else {
c2cdce
 		*delayp = rate->ops.output_frames(rate->obj, slave_delay)
c2cdce
-				+ snd_pcm_mmap_capture_hw_avail(pcm);
c2cdce
+				+ snd_pcm_mmap_capture_delay(pcm);
c2cdce
 	}
c2cdce
 	return 0;
c2cdce
 }
c2cdce
@@ -1157,12 +1157,8 @@ static int snd_pcm_rate_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 		status->avail = snd_pcm_mmap_playback_avail(pcm);
c2cdce
 		status->avail_max = rate->ops.input_frames(rate->obj, status->avail_max);
c2cdce
 	} else {
c2cdce
-		/* FIXME: Maybe possible to somthing similar to
c2cdce
-		 * snd_pcm_rate_playback_internal_delay()
c2cdce
-		 * for the capture case.
c2cdce
-		 */
c2cdce
 		status->delay = rate->ops.output_frames(rate->obj, status->delay)
c2cdce
-					+ snd_pcm_mmap_capture_hw_avail(pcm);
c2cdce
+					+ snd_pcm_mmap_capture_delay(pcm);
c2cdce
 		status->avail = snd_pcm_mmap_capture_avail(pcm);
c2cdce
 		status->avail_max = rate->ops.output_frames(rate->obj, status->avail_max);
c2cdce
 	}
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 437b5b3aae8b1d9f65289f563deb0fa6356a0fa6 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 7 Jan 2021 17:32:11 +0100
c2cdce
Subject: [PATCH 34/49] ucm: fix possible memory leak in parse_verb_file()
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/ucm/parser.c | 2 +-
c2cdce
 1 file changed, 1 insertion(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/ucm/parser.c b/src/ucm/parser.c
c2cdce
index 75b78826..c8bee1f2 100644
c2cdce
--- a/src/ucm/parser.c
c2cdce
+++ b/src/ucm/parser.c
c2cdce
@@ -1575,7 +1575,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
c2cdce
 	/* in-place evaluation */
c2cdce
 	err = uc_mgr_evaluate_inplace(uc_mgr, cfg);
c2cdce
 	if (err < 0)
c2cdce
-		return err;
c2cdce
+		goto _err;
c2cdce
 
c2cdce
 	/* parse master config sections */
c2cdce
 	snd_config_for_each(i, next, cfg) {
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From d0bb8f84c92357bfd0e024efe5f6d53a963c4d7a Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 7 Jan 2021 17:34:00 +0100
c2cdce
Subject: [PATCH 35/49] topology: tplg_pprint_integer() fix coverity
c2cdce
 uninitalized variable error
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/topology/save.c | 2 ++
c2cdce
 1 file changed, 2 insertions(+)
c2cdce
c2cdce
diff --git a/src/topology/save.c b/src/topology/save.c
c2cdce
index c7a5a801..f7af7af3 100644
c2cdce
--- a/src/topology/save.c
c2cdce
+++ b/src/topology/save.c
c2cdce
@@ -133,6 +133,8 @@ static int tplg_pprint_integer(snd_config_t *n, char **ret)
c2cdce
 		if (llval < INT_MIN || llval > UINT_MAX)
c2cdce
 			return snd_config_get_ascii(n, ret);
c2cdce
 		lval = llval;
c2cdce
+	} else {
c2cdce
+		lval = 0;
c2cdce
 	}
c2cdce
 	err = tplg_nice_value_format(buf, sizeof(buf), (unsigned int)lval);
c2cdce
 	if (err < 0)
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From b8764a061b83284be60adc01c1f7b035c4484ace Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 7 Jan 2021 17:36:04 +0100
c2cdce
Subject: [PATCH 36/49] topology: tplg_add_widget_object() - do not use invalid
c2cdce
 elem_ctl
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/topology/dapm.c | 1 +
c2cdce
 1 file changed, 1 insertion(+)
c2cdce
c2cdce
diff --git a/src/topology/dapm.c b/src/topology/dapm.c
c2cdce
index 92dc01aa..f6a84a60 100644
c2cdce
--- a/src/topology/dapm.c
c2cdce
+++ b/src/topology/dapm.c
c2cdce
@@ -836,6 +836,7 @@ int tplg_add_widget_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
c2cdce
 		default:
c2cdce
 			SNDERR("widget %s: invalid type %d for ctl %d",
c2cdce
 				wt->name, ct->type, i);
c2cdce
+			ret = -EINVAL;
c2cdce
 			break;
c2cdce
 		}
c2cdce
 
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 0dbaba95f4bc59602bf2d3fb12a60db7444e5892 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 7 Jan 2021 17:38:50 +0100
c2cdce
Subject: [PATCH 37/49] topology: tplg_decode_pcm() - add missing log argument
c2cdce
 (compress)
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/topology/pcm.c | 2 +-
c2cdce
 1 file changed, 1 insertion(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
c2cdce
index c8f41862..a473b59b 100644
c2cdce
--- a/src/topology/pcm.c
c2cdce
+++ b/src/topology/pcm.c
c2cdce
@@ -2020,7 +2020,7 @@ next:
c2cdce
 	pt->playback = pcm->playback;
c2cdce
 	pt->capture = pcm->capture;
c2cdce
 	pt->compress = pcm->compress;
c2cdce
-	tplg_log(tplg, 'D', pos, "pcm: playback %d capture %d compress",
c2cdce
+	tplg_log(tplg, 'D', pos, "pcm: playback %d capture %d compress %d",
c2cdce
 		 pt->playback, pt->capture, pt->compress);
c2cdce
 	pt->num_streams = pcm->num_streams;
c2cdce
 	pt->flag_mask = pcm->flag_mask;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 51e1d486ce4535923692bd1d7e59d5aa3a29cd50 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 7 Jan 2021 17:40:42 +0100
c2cdce
Subject: [PATCH 38/49] topology: parse_tuple_set() - remove dead condition
c2cdce
 code
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/topology/data.c | 2 +-
c2cdce
 1 file changed, 1 insertion(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/topology/data.c b/src/topology/data.c
c2cdce
index c2931bd2..5633cdc3 100644
c2cdce
--- a/src/topology/data.c
c2cdce
+++ b/src/topology/data.c
c2cdce
@@ -860,7 +860,7 @@ static int parse_tuple_set(snd_config_t *cfg,
c2cdce
 			}
c2cdce
 
c2cdce
 			if ((type == SND_SOC_TPLG_TUPLE_TYPE_WORD
c2cdce
-					&& tuple_val > UINT_MAX)
c2cdce
+					/* && tuple_val > UINT_MAX */)
c2cdce
 				|| (type == SND_SOC_TPLG_TUPLE_TYPE_SHORT
c2cdce
 					&& tuple_val > USHRT_MAX)
c2cdce
 				|| (type == SND_SOC_TPLG_TUPLE_TYPE_BYTE
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 3f63dc26445ae7c215e48a57af83b6da325f166d Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 7 Jan 2021 17:41:38 +0100
c2cdce
Subject: [PATCH 39/49] ucm: uc_mgr_substitute_tree() fix use after free
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/ucm/ucm_subs.c | 3 ++-
c2cdce
 1 file changed, 2 insertions(+), 1 deletion(-)
c2cdce
c2cdce
diff --git a/src/ucm/ucm_subs.c b/src/ucm/ucm_subs.c
c2cdce
index f608bb09..df6d736f 100644
c2cdce
--- a/src/ucm/ucm_subs.c
c2cdce
+++ b/src/ucm/ucm_subs.c
c2cdce
@@ -417,11 +417,12 @@ int uc_mgr_substitute_tree(snd_use_case_mgr_t *uc_mgr, snd_config_t *node)
c2cdce
 		if (err < 0)
c2cdce
 			return err;
c2cdce
 		err = snd_config_set_id(node, s);
c2cdce
-		free(s);
c2cdce
 		if (err < 0) {
c2cdce
 			uc_error("unable to set substituted id '%s' (old id '%s')", s, id);
c2cdce
+			free(s);
c2cdce
 			return err;
c2cdce
 		}
c2cdce
+		free(s);
c2cdce
 	}
c2cdce
 	if (snd_config_get_type(node) != SND_CONFIG_TYPE_COMPOUND) {
c2cdce
 		if (snd_config_get_type(node) == SND_CONFIG_TYPE_STRING) {
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 45f503632acf24877c466a7c1c74d8a26414bf3e Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 7 Jan 2021 17:45:27 +0100
c2cdce
Subject: [PATCH 40/49] topology: sort_config() cleanups - use goto for the
c2cdce
 error path
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/topology/save.c | 15 +++++++--------
c2cdce
 1 file changed, 7 insertions(+), 8 deletions(-)
c2cdce
c2cdce
diff --git a/src/topology/save.c b/src/topology/save.c
c2cdce
index f7af7af3..fecbc6a5 100644
c2cdce
--- a/src/topology/save.c
c2cdce
+++ b/src/topology/save.c
c2cdce
@@ -180,29 +180,28 @@ static snd_config_t *sort_config(const char *id, snd_config_t *src)
c2cdce
 	}
c2cdce
 	if (array <= 0)
c2cdce
 		qsort(a, count, sizeof(a[0]), _compar);
c2cdce
-	if (snd_config_make_compound(&dst, id, count == 1)) {
c2cdce
-		free(a);
c2cdce
-		return NULL;
c2cdce
-	}
c2cdce
+	if (snd_config_make_compound(&dst, id, count == 1))
c2cdce
+		goto lerr;
c2cdce
 	for (index = 0; index < count; index++) {
c2cdce
 		snd_config_t *s = a[index];
c2cdce
 		const char *id2;
c2cdce
 		if (snd_config_get_id(s, &id2)) {
c2cdce
 			snd_config_delete(dst);
c2cdce
-			free(a);
c2cdce
-			return NULL;
c2cdce
+			goto lerr;
c2cdce
 		}
c2cdce
 		s = sort_config(id2, s);
c2cdce
 		if (s == NULL || snd_config_add(dst, s)) {
c2cdce
 			if (s)
c2cdce
 				snd_config_delete(s);
c2cdce
 			snd_config_delete(dst);
c2cdce
-			free(a);
c2cdce
-			return NULL;
c2cdce
+			goto lerr;
c2cdce
 		}
c2cdce
 	}
c2cdce
 	free(a);
c2cdce
 	return dst;
c2cdce
+lerr:
c2cdce
+	free(a);
c2cdce
+	return NULL;
c2cdce
 }
c2cdce
 
c2cdce
 static int tplg_check_quoted(const unsigned char *p)
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 93752fb4de397554e92a4eb9079f77dabaec7d7f Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 7 Jan 2021 17:49:25 +0100
c2cdce
Subject: [PATCH 41/49] conf: USB - add "Xonar U7 MKII" to
c2cdce
 USB-Audio.pcm.iec958_device
c2cdce
c2cdce
BugLink: https://github.com/alsa-project/alsa-lib/issues/100
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/conf/cards/USB-Audio.conf | 1 +
c2cdce
 1 file changed, 1 insertion(+)
c2cdce
c2cdce
diff --git a/src/conf/cards/USB-Audio.conf b/src/conf/cards/USB-Audio.conf
c2cdce
index 9b64af3c..b1b74b02 100644
c2cdce
--- a/src/conf/cards/USB-Audio.conf
c2cdce
+++ b/src/conf/cards/USB-Audio.conf
c2cdce
@@ -39,6 +39,7 @@ USB-Audio.pcm.iec958_device {
c2cdce
 	# "NoiseBlaster 3000" 42
c2cdce
 	"USB Sound Blaster HD" 1
c2cdce
 	"Xonar U7" 1
c2cdce
+	"Xonar U7 MKII" 1
c2cdce
 	"ASUS XONAR U5" 1
c2cdce
 	"XONAR U5" 1
c2cdce
 	"XONAR SOUND CARD" 1
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 644514e85da169670e4a490b7b15b5ecfcec92c0 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Mon, 18 Jan 2021 21:09:43 +0100
c2cdce
Subject: [PATCH 42/49] pcm_plugin: set the initial hw_ptr/appl_ptr from the
c2cdce
 child pcm
c2cdce
c2cdce
The direct plugins (dmix & etc.) sets own initial
c2cdce
hw_ptr and appl_ptr. Use this initial settings
c2cdce
to export correct values in snd_pcm_status().
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_plugin.c | 32 +++++++++++++++++---------------
c2cdce
 1 file changed, 17 insertions(+), 15 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
c2cdce
index 7ed6f25a..ff254eba 100644
c2cdce
--- a/src/pcm/pcm_plugin.c
c2cdce
+++ b/src/pcm/pcm_plugin.c
c2cdce
@@ -146,15 +146,14 @@ static int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
c2cdce
 	return 0;
c2cdce
 }
c2cdce
 
c2cdce
-static int snd_pcm_plugin_prepare(snd_pcm_t *pcm)
c2cdce
+static int snd_pcm_plugin_call_init_cb(snd_pcm_t *pcm, snd_pcm_plugin_t *plugin)
c2cdce
 {
c2cdce
-	snd_pcm_plugin_t *plugin = pcm->private_data;
c2cdce
+	snd_pcm_t *slave = plugin->gen.slave;
c2cdce
 	int err;
c2cdce
-	err = snd_pcm_prepare(plugin->gen.slave);
c2cdce
-	if (err < 0)
c2cdce
-		return err;
c2cdce
-	*pcm->hw.ptr = 0;
c2cdce
-	*pcm->appl.ptr = 0;
c2cdce
+
c2cdce
+	assert(pcm->boundary == slave->boundary);
c2cdce
+	*pcm->hw.ptr = *slave->hw.ptr;
c2cdce
+	*pcm->appl.ptr = *slave->appl.ptr;
c2cdce
 	if (plugin->init) {
c2cdce
 		err = plugin->init(pcm);
c2cdce
 		if (err < 0)
c2cdce
@@ -163,6 +162,16 @@ static int snd_pcm_plugin_prepare(snd_pcm_t *pcm)
c2cdce
 	return 0;
c2cdce
 }
c2cdce
 
c2cdce
+static int snd_pcm_plugin_prepare(snd_pcm_t *pcm)
c2cdce
+{
c2cdce
+	snd_pcm_plugin_t *plugin = pcm->private_data;
c2cdce
+	int err;
c2cdce
+	err = snd_pcm_prepare(plugin->gen.slave);
c2cdce
+	if (err < 0)
c2cdce
+		return err;
c2cdce
+	return snd_pcm_plugin_call_init_cb(pcm, plugin);
c2cdce
+}
c2cdce
+
c2cdce
 static int snd_pcm_plugin_reset(snd_pcm_t *pcm)
c2cdce
 {
c2cdce
 	snd_pcm_plugin_t *plugin = pcm->private_data;
c2cdce
@@ -170,14 +179,7 @@ static int snd_pcm_plugin_reset(snd_pcm_t *pcm)
c2cdce
 	err = snd_pcm_reset(plugin->gen.slave);
c2cdce
 	if (err < 0)
c2cdce
 		return err;
c2cdce
-	*pcm->hw.ptr = 0;
c2cdce
-	*pcm->appl.ptr = 0;
c2cdce
-	if (plugin->init) {
c2cdce
-		err = plugin->init(pcm);
c2cdce
-		if (err < 0)
c2cdce
-			return err;
c2cdce
-	}
c2cdce
-	return 0;
c2cdce
+	return snd_pcm_plugin_call_init_cb(pcm, plugin);
c2cdce
 }
c2cdce
 
c2cdce
 static snd_pcm_sframes_t snd_pcm_plugin_rewindable(snd_pcm_t *pcm)
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 0de72e63d7bd180566c71f6fb01d7719525ee326 Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Tue, 19 Jan 2021 11:17:00 +0100
c2cdce
Subject: [PATCH 43/49] pcm: dmix/dshare - delay calculation fixes and cleanups
c2cdce
c2cdce
Unfortunately, we cannot use status->avail from slave, because this value
c2cdce
does not wrap to the buffer size and it may even overflow slave boundary
c2cdce
(endless run). We can use only hw_ptr from slave.
c2cdce
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_dmix.c   | 5 ++---
c2cdce
 src/pcm/pcm_dshare.c | 5 ++---
c2cdce
 2 files changed, 4 insertions(+), 6 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
c2cdce
index 5b7472d9..be2675af 100644
c2cdce
--- a/src/pcm/pcm_dmix.c
c2cdce
+++ b/src/pcm/pcm_dmix.c
c2cdce
@@ -488,8 +488,7 @@ static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 	case SNDRV_PCM_STATE_DRAINING:
c2cdce
 	case SNDRV_PCM_STATE_RUNNING:
c2cdce
 		snd_pcm_dmix_sync_ptr0(pcm, status->hw_ptr);
c2cdce
-		status->delay += snd_pcm_mmap_playback_delay(pcm)
c2cdce
-				+ status->avail - dmix->spcm->buffer_size;
c2cdce
+		status->delay = snd_pcm_mmap_playback_delay(pcm);
c2cdce
 		break;
c2cdce
 	default:
c2cdce
 		break;
c2cdce
@@ -518,7 +517,7 @@ static int snd_pcm_dmix_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
c2cdce
 	case SNDRV_PCM_STATE_PREPARED:
c2cdce
 	case SNDRV_PCM_STATE_SUSPENDED:
c2cdce
 	case STATE_RUN_PENDING:
c2cdce
-		*delayp = snd_pcm_mmap_playback_hw_avail(pcm);
c2cdce
+		*delayp = snd_pcm_mmap_playback_delay(pcm);
c2cdce
 		return 0;
c2cdce
 	case SNDRV_PCM_STATE_XRUN:
c2cdce
 		return -EPIPE;
c2cdce
diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
c2cdce
index 8a672572..10243013 100644
c2cdce
--- a/src/pcm/pcm_dshare.c
c2cdce
+++ b/src/pcm/pcm_dshare.c
c2cdce
@@ -237,8 +237,7 @@ static int snd_pcm_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 	case SNDRV_PCM_STATE_DRAINING:
c2cdce
 	case SNDRV_PCM_STATE_RUNNING:
c2cdce
 		snd_pcm_dshare_sync_ptr0(pcm, status->hw_ptr);
c2cdce
-		status->delay += snd_pcm_mmap_playback_delay(pcm)
c2cdce
-				+ status->avail - dshare->spcm->buffer_size;
c2cdce
+		status->delay += snd_pcm_mmap_playback_delay(pcm);
c2cdce
 		break;
c2cdce
 	default:
c2cdce
 		break;
c2cdce
@@ -290,7 +289,7 @@ static int snd_pcm_dshare_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
c2cdce
 	case SNDRV_PCM_STATE_PREPARED:
c2cdce
 	case SNDRV_PCM_STATE_SUSPENDED:
c2cdce
 	case STATE_RUN_PENDING:
c2cdce
-		*delayp = snd_pcm_mmap_playback_hw_avail(pcm);
c2cdce
+		*delayp = snd_pcm_mmap_playback_delay(pcm);
c2cdce
 		return 0;
c2cdce
 	case SNDRV_PCM_STATE_XRUN:
c2cdce
 		return -EPIPE;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From ae7362c996e0b991c399cc26c6d0b3c8e295e83c Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Wed, 20 Jan 2021 16:58:33 +0100
c2cdce
Subject: [PATCH 44/49] topology: fix 'parse_tuple_set() - remove dead
c2cdce
 condition code'
c2cdce
c2cdce
The whole SND_SOC_TPLG_TUPLE_TYPE_WORD condition part must be
c2cdce
commented out, otherwise the condition is always true.
c2cdce
c2cdce
Fixes: 51e1d486ce ("topology: parse_tuple_set() - remove dead condition code")
c2cdce
BugLink: https://github.com/alsa-project/alsa-lib/issues/114
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/topology/data.c | 10 +++++-----
c2cdce
 1 file changed, 5 insertions(+), 5 deletions(-)
c2cdce
c2cdce
diff --git a/src/topology/data.c b/src/topology/data.c
c2cdce
index 5633cdc3..0546d63e 100644
c2cdce
--- a/src/topology/data.c
c2cdce
+++ b/src/topology/data.c
c2cdce
@@ -859,11 +859,11 @@ static int parse_tuple_set(snd_config_t *cfg,
c2cdce
 				goto err;
c2cdce
 			}
c2cdce
 
c2cdce
-			if ((type == SND_SOC_TPLG_TUPLE_TYPE_WORD
c2cdce
-					/* && tuple_val > UINT_MAX */)
c2cdce
-				|| (type == SND_SOC_TPLG_TUPLE_TYPE_SHORT
c2cdce
-					&& tuple_val > USHRT_MAX)
c2cdce
-				|| (type == SND_SOC_TPLG_TUPLE_TYPE_BYTE
c2cdce
+			if (/* (type == SND_SOC_TPLG_TUPLE_TYPE_WORD
c2cdce
+					&& tuple_val > UINT_MAX) || */
c2cdce
+				(type == SND_SOC_TPLG_TUPLE_TYPE_SHORT
c2cdce
+					&& tuple_val > USHRT_MAX) ||
c2cdce
+				(type == SND_SOC_TPLG_TUPLE_TYPE_BYTE
c2cdce
 					&& tuple_val > UCHAR_MAX)) {
c2cdce
 				SNDERR("tuple %s: invalid value", id);
c2cdce
 				goto err;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From f2c1a9f3279a30cbd8dcba1eaf0d52f50b56b886 Mon Sep 17 00:00:00 2001
c2cdce
From: Takashi Iwai <tiwai@suse.de>
c2cdce
Date: Fri, 22 Jan 2021 15:48:39 +0100
c2cdce
Subject: [PATCH 45/49] pcm: direct: Fix the missing appl_ptr update
c2cdce
c2cdce
A snd_pcm_status() call for the direct plugins receives the status
c2cdce
from the slave PCM, but this doesn't contain a valid appl_ptr, since
c2cdce
the slave PCM for the direct plugins is in a free-wheel mode, hence
c2cdce
the appl_ptr is always zero.  This result in the inconsistent
c2cdce
status->appl_ptr and pcm->appl.ptr, hitting the recently introduced
c2cdce
assert() call.
c2cdce
c2cdce
Fix it by transferring the plugin's appl_ptr to the upper caller.
c2cdce
c2cdce
BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1181194
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_dmix.c   | 1 +
c2cdce
 src/pcm/pcm_dshare.c | 1 +
c2cdce
 src/pcm/pcm_dsnoop.c | 1 +
c2cdce
 3 files changed, 3 insertions(+)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
c2cdce
index be2675af..d8495065 100644
c2cdce
--- a/src/pcm/pcm_dmix.c
c2cdce
+++ b/src/pcm/pcm_dmix.c
c2cdce
@@ -495,6 +495,7 @@ static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 	}
c2cdce
 
c2cdce
 	status->state = snd_pcm_dmix_state(pcm);
c2cdce
+	status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */
c2cdce
 	status->trigger_tstamp = dmix->trigger_tstamp;
c2cdce
 	status->avail = snd_pcm_mmap_playback_avail(pcm);
c2cdce
 	status->avail_max = status->avail > dmix->avail_max ? status->avail : dmix->avail_max;
c2cdce
diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
c2cdce
index 10243013..dccb137b 100644
c2cdce
--- a/src/pcm/pcm_dshare.c
c2cdce
+++ b/src/pcm/pcm_dshare.c
c2cdce
@@ -243,6 +243,7 @@ static int snd_pcm_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 		break;
c2cdce
 	}
c2cdce
 	status->state = snd_pcm_dshare_state(pcm);
c2cdce
+	status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */
c2cdce
 	status->trigger_tstamp = dshare->trigger_tstamp;
c2cdce
 	status->avail = snd_pcm_mmap_playback_avail(pcm);
c2cdce
 	status->avail_max = status->avail > dshare->avail_max ? status->avail : dshare->avail_max;
c2cdce
diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
c2cdce
index c6e8cd27..695bf4aa 100644
c2cdce
--- a/src/pcm/pcm_dsnoop.c
c2cdce
+++ b/src/pcm/pcm_dsnoop.c
c2cdce
@@ -193,6 +193,7 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 	snd_pcm_status(dsnoop->spcm, status);
c2cdce
 	state = snd_pcm_state(dsnoop->spcm);
c2cdce
 	status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state;
c2cdce
+	status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */
c2cdce
 	status->trigger_tstamp = dsnoop->trigger_tstamp;
c2cdce
 	status->avail = snd_pcm_mmap_capture_avail(pcm);
c2cdce
 	status->avail_max = status->avail > dsnoop->avail_max ? status->avail : dsnoop->avail_max;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 26fdcb98e6be186016d53f87d06ae47aabe5b7fc Mon Sep 17 00:00:00 2001
c2cdce
From: Takashi Iwai <tiwai@suse.de>
c2cdce
Date: Fri, 22 Jan 2021 15:48:40 +0100
c2cdce
Subject: [PATCH 46/49] pcm: ioplug: Pass appl_ptr and hw_ptr in
c2cdce
 snd_pcm_status()
c2cdce
c2cdce
The snd_pcm_status() of the ioplug doesn't return the current
c2cdce
positions of hw_ptr and appl_ptr as advertised.  Fix it by copying the
c2cdce
current values stored in the plugin data.
c2cdce
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_ioplug.c | 2 ++
c2cdce
 1 file changed, 2 insertions(+)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c
c2cdce
index e141b1f9..a1463bf6 100644
c2cdce
--- a/src/pcm/pcm_ioplug.c
c2cdce
+++ b/src/pcm/pcm_ioplug.c
c2cdce
@@ -133,6 +133,8 @@ static int snd_pcm_ioplug_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 	gettimestamp(&status->tstamp, pcm->tstamp_type);
c2cdce
 	status->avail = snd_pcm_mmap_avail(pcm);
c2cdce
 	status->avail_max = io->avail_max;
c2cdce
+	status->appl_ptr = *pcm->appl.ptr;
c2cdce
+	status->hw_ptr = *pcm->hw.ptr;
c2cdce
 	if (snd_pcm_ioplug_delay(pcm, &sd) < 0)
c2cdce
 		sd = snd_pcm_mmap_delay(pcm);
c2cdce
 	status->delay = sd;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From bcc762f99ad642cc0dd9eaceb51f228eba9fe68c Mon Sep 17 00:00:00 2001
c2cdce
From: Takashi Iwai <tiwai@suse.de>
c2cdce
Date: Fri, 22 Jan 2021 15:48:41 +0100
c2cdce
Subject: [PATCH 47/49] pcm: null: Pass appl_ptr and hw_ptr in snd_pcm_status()
c2cdce
c2cdce
Just like the previous fix for ioplug, the null plugin also misses the
c2cdce
appl_ptr and hw_ptr updates for snd_pcm_status().  Fix it as well.
c2cdce
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_null.c | 2 ++
c2cdce
 1 file changed, 2 insertions(+)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_null.c b/src/pcm/pcm_null.c
c2cdce
index 1d815485..c8ea9b38 100644
c2cdce
--- a/src/pcm/pcm_null.c
c2cdce
+++ b/src/pcm/pcm_null.c
c2cdce
@@ -96,6 +96,8 @@ static int snd_pcm_null_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
c2cdce
 	memset(status, 0, sizeof(*status));
c2cdce
 	status->state = null->state;
c2cdce
 	status->trigger_tstamp = null->trigger_tstamp;
c2cdce
+	status->appl_ptr = *pcm->appl.ptr;
c2cdce
+	status->hw_ptr = *pcm->hw.ptr;
c2cdce
 	gettimestamp(&status->tstamp, pcm->tstamp_type);
c2cdce
 	status->avail = snd_pcm_null_avail_update(pcm);
c2cdce
 	status->avail_max = pcm->buffer_size;
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 55d59821ffb8f44395cf2b7a424d6523da58e66a Mon Sep 17 00:00:00 2001
c2cdce
From: Takashi Iwai <tiwai@suse.de>
c2cdce
Date: Fri, 22 Jan 2021 15:48:42 +0100
c2cdce
Subject: [PATCH 48/49] pcm: share: Pass appl_ptr and hw_ptr in
c2cdce
 snd_pcm_status()
c2cdce
c2cdce
This one also has the same problem as others; the appl_ptr and hw_ptr
c2cdce
of share plugin aren't updated in snd_pcm_status() call.  Fix it.
c2cdce
c2cdce
Signed-off-by: Takashi Iwai <tiwai@suse.de>
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm_share.c | 2 ++
c2cdce
 1 file changed, 2 insertions(+)
c2cdce
c2cdce
diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c
c2cdce
index bff9507d..72509491 100644
c2cdce
--- a/src/pcm/pcm_share.c
c2cdce
+++ b/src/pcm/pcm_share.c
c2cdce
@@ -711,6 +711,8 @@ static int snd_pcm_share_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
c2cdce
  _notrunning:
c2cdce
 	status->delay = sd + d;
c2cdce
 	status->state = share->state;
c2cdce
+	status->appl_ptr = *pcm->appl.ptr;
c2cdce
+	status->hw_ptr = *pcm->hw.ptr;
c2cdce
 	status->trigger_tstamp = share->trigger_tstamp;
c2cdce
  _end:
c2cdce
 	Pthread_mutex_unlock(&slave->mutex);
c2cdce
-- 
c2cdce
2.29.2
c2cdce
c2cdce
c2cdce
From 00eafe98eebff8ecd1ecdc58470068bfd610cc8d Mon Sep 17 00:00:00 2001
c2cdce
From: Jaroslav Kysela <perex@perex.cz>
c2cdce
Date: Thu, 21 Jan 2021 15:45:49 +0100
c2cdce
Subject: [PATCH 49/49] pcm: pcm_ioplug - fix the avail_update mmap capture
c2cdce
 copy issue
c2cdce
c2cdce
It seems that the commit "pcm: ioplug: Transfer all available data"
c2cdce
introduced new regressions (wrong memory access). The second issue
c2cdce
is that the avail_update in ioplug does not move appl_ptr nor hw_ptr,
c2cdce
so it's possible that the transfers may be repetitive.
c2cdce
c2cdce
This patch moves the transfer calls to mmap_begin callback where it
c2cdce
should be. The pointer wraps are handled by design now.
c2cdce
c2cdce
Fixes: 1714332719 ("pcm: ioplug: Transfer all available data")
c2cdce
BugLink: https://github.com/alsa-project/alsa-lib/pull/103
c2cdce
Tested-by: Andreas Pape <apape@de.adit-jv.com>
c2cdce
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
c2cdce
---
c2cdce
 src/pcm/pcm.c        | 20 ++++++++++-----
c2cdce
 src/pcm/pcm_ioplug.c | 60 +++++++++++++++++++++++++-------------------
c2cdce
 src/pcm/pcm_local.h  |  2 ++
c2cdce
 3 files changed, 50 insertions(+), 32 deletions(-)
c2cdce
c2cdce
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
c2cdce
index 24030b31..a57ce5d9 100644
c2cdce
--- a/src/pcm/pcm.c
c2cdce
+++ b/src/pcm/pcm.c
c2cdce
@@ -7218,9 +7218,8 @@ int snd_pcm_mmap_begin(snd_pcm_t *pcm,
c2cdce
 }
c2cdce
 
c2cdce
 #ifndef DOC_HIDDEN
c2cdce
-/* locked version */
c2cdce
-int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
c2cdce
-		       snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
c2cdce
+int __snd_pcm_mmap_begin_generic(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
c2cdce
+				 snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
c2cdce
 {
c2cdce
 	snd_pcm_uframes_t cont;
c2cdce
 	snd_pcm_uframes_t f;
c2cdce
@@ -7229,9 +7228,6 @@ int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
c2cdce
 
c2cdce
 	assert(pcm && areas && offset && frames);
c2cdce
 
c2cdce
-	if (pcm->fast_ops->mmap_begin)
c2cdce
-		return pcm->fast_ops->mmap_begin(pcm->fast_op_arg, areas, offset, frames);
c2cdce
-
c2cdce
 	/* fallback for plugins that do not specify new callback */
c2cdce
 	xareas = snd_pcm_mmap_areas(pcm);
c2cdce
 	if (xareas == NULL)
c2cdce
@@ -7250,6 +7246,18 @@ int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
c2cdce
 	*frames = f;
c2cdce
 	return 0;
c2cdce
 }
c2cdce
+
c2cdce
+/* locked version */
c2cdce
+int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
c2cdce
+			 snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
c2cdce
+{
c2cdce
+	assert(pcm && areas && offset && frames);
c2cdce
+
c2cdce
+	if (pcm->fast_ops->mmap_begin)
c2cdce
+		return pcm->fast_ops->mmap_begin(pcm->fast_op_arg, areas, offset, frames);
c2cdce
+
c2cdce
+	return __snd_pcm_mmap_begin_generic(pcm, areas, offset, frames);
c2cdce
+}
c2cdce
 #endif
c2cdce
 
c2cdce
 /**
c2cdce
diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c
c2cdce
index a1463bf6..98184398 100644
c2cdce
--- a/src/pcm/pcm_ioplug.c
c2cdce
+++ b/src/pcm/pcm_ioplug.c
c2cdce
@@ -697,6 +697,38 @@ static snd_pcm_sframes_t snd_pcm_ioplug_readn(snd_pcm_t *pcm, void **bufs, snd_p
c2cdce
 	}
c2cdce
 }
c2cdce
 
c2cdce
+static int snd_pcm_ioplug_mmap_begin_capture(snd_pcm_t *pcm,
c2cdce
+					     const snd_pcm_channel_area_t **areas,
c2cdce
+					     snd_pcm_uframes_t *offset,
c2cdce
+					     snd_pcm_uframes_t *frames)
c2cdce
+{
c2cdce
+	ioplug_priv_t *io = pcm->private_data;
c2cdce
+	int err;
c2cdce
+
c2cdce
+	err = __snd_pcm_mmap_begin_generic(pcm, areas, offset, frames);
c2cdce
+	if (err < 0)
c2cdce
+		return err;
c2cdce
+
c2cdce
+	if (io->data->callback->transfer &&
c2cdce
+	    pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED &&
c2cdce
+	    pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
c2cdce
+		snd_pcm_sframes_t result;
c2cdce
+		result = io->data->callback->transfer(io->data, *areas, *offset, *frames);
c2cdce
+		if (result < 0)
c2cdce
+			return result;
c2cdce
+	}
c2cdce
+
c2cdce
+	return err;
c2cdce
+}
c2cdce
+
c2cdce
+static int snd_pcm_ioplug_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
c2cdce
+				     snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
c2cdce
+{
c2cdce
+	if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
c2cdce
+		return __snd_pcm_mmap_begin_generic(pcm, areas, offset, frames);
c2cdce
+	return snd_pcm_ioplug_mmap_begin_capture(pcm, areas, offset, frames);
c2cdce
+}
c2cdce
+
c2cdce
 static snd_pcm_sframes_t snd_pcm_ioplug_mmap_commit(snd_pcm_t *pcm,
c2cdce
 						    snd_pcm_uframes_t offset,
c2cdce
 						    snd_pcm_uframes_t size)
c2cdce
@@ -707,7 +739,7 @@ static snd_pcm_sframes_t snd_pcm_ioplug_mmap_commit(snd_pcm_t *pcm,
c2cdce
 		const snd_pcm_channel_area_t *areas;
c2cdce
 		snd_pcm_uframes_t ofs, frames = size;
c2cdce
 
c2cdce
-		__snd_pcm_mmap_begin(pcm, &areas, &ofs, &frames);
c2cdce
+		__snd_pcm_mmap_begin_generic(pcm, &areas, &ofs, &frames);
c2cdce
 		if (ofs != offset)
c2cdce
 			return -EIO;
c2cdce
 		return ioplug_priv_transfer_areas(pcm, areas, offset, frames);
c2cdce
@@ -727,31 +759,6 @@ static snd_pcm_sframes_t snd_pcm_ioplug_avail_update(snd_pcm_t *pcm)
c2cdce
 		return -EPIPE;
c2cdce
 
c2cdce
 	avail = snd_pcm_mmap_avail(pcm);
c2cdce
-	if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
c2cdce
-	    pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED &&
c2cdce
-	    pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
c2cdce
-		if (io->data->callback->transfer) {
c2cdce
-			const snd_pcm_channel_area_t *areas;
c2cdce
-			snd_pcm_uframes_t offset, size = UINT_MAX;
c2cdce
-			snd_pcm_sframes_t result;
c2cdce
-
c2cdce
-			__snd_pcm_mmap_begin(pcm, &areas, &offset, &size);
c2cdce
-			result = io->data->callback->transfer(io->data, areas, offset, size);
c2cdce
-			if (result < 0)
c2cdce
-				return result;
c2cdce
-
c2cdce
-			/* If the available data doesn't fit in the
c2cdce
-			   contiguous area at the end of the mmap we
c2cdce
-			   must transfer the remaining data to the
c2cdce
-			   beginning of the mmap. */
c2cdce
-			if (size < avail) {
c2cdce
-				result = io->data->callback->transfer(io->data, areas,
c2cdce
-								      0, avail - size);
c2cdce
-				if (result < 0)
c2cdce
-					return result;
c2cdce
-			}
c2cdce
-		}
c2cdce
-	}
c2cdce
 	if (avail > io->avail_max)
c2cdce
 		io->avail_max = avail;
c2cdce
 	return (snd_pcm_sframes_t)avail;
c2cdce
@@ -947,6 +954,7 @@ static const snd_pcm_fast_ops_t snd_pcm_ioplug_fast_ops = {
c2cdce
 	.poll_descriptors_count = snd_pcm_ioplug_poll_descriptors_count,
c2cdce
 	.poll_descriptors = snd_pcm_ioplug_poll_descriptors,
c2cdce
 	.poll_revents = snd_pcm_ioplug_poll_revents,
c2cdce
+	.mmap_begin = snd_pcm_ioplug_mmap_begin,
c2cdce
 };
c2cdce
 
c2cdce
 #endif /* !DOC_HIDDEN */
c2cdce
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
c2cdce
index bec5a408..a63f4be0 100644
c2cdce
--- a/src/pcm/pcm_local.h
c2cdce
+++ b/src/pcm/pcm_local.h
c2cdce
@@ -420,6 +420,8 @@ int _snd_pcm_poll_descriptor(snd_pcm_t *pcm);
c2cdce
 #define _snd_pcm_async_descriptor _snd_pcm_poll_descriptor /* FIXME */
c2cdce
 
c2cdce
 /* locked versions */
c2cdce
+int __snd_pcm_mmap_begin_generic(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
c2cdce
+				 snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames);
c2cdce
 int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas,
c2cdce
 			 snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames);
c2cdce
 snd_pcm_sframes_t __snd_pcm_mmap_commit(snd_pcm_t *pcm,
c2cdce
-- 
c2cdce
2.29.2
c2cdce