All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops
@ 2017-05-21 20:09 Takashi Iwai
  2017-05-21 20:09   ` Takashi Iwai
                   ` (15 more replies)
  0 siblings, 16 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Hi,

this is a part of the previous RFC patchset, and it's preliminary for
eliminating set_fs() usages in the rest ALSA codes.  This patchset
itself converts the existing copy and silence PCM ops to a new single
copy_silence ops.  The new callback takes in_kernel flag for allowing
in-kernel buffer copy, so that the PCM drivers can pass the buffer in
kernel-space later directly without set_fs() hackery.

The latest codes are found in topic/kill-set_fs branch of sound git
tree.

The media people are Cc'ed for solo6x10 changes.


Takashi

===

Takashi Iwai (16):
  ALSA: pcm: Introduce copy_silence PCM ops
  ALSA: Update document about copy_silence PCM ops
  ALSA: dummy: Convert to copy_silence ops
  ALSA: es1938: Convert to copy_silence ops
  ALSA: korg1212: Convert to copy_silence ops
  ALSA: nm256: Convert to copy_silence ops
  ALSA: rme32: Convert to copy_silence ops
  ALSA: rme96: Convert to copy_silence ops
  ALSA: rme9652: Convert to copy_silence ops
  ALSA: hdsp: Convert to copy_silence ops
  ALSA: gus: Convert to copy_silence ops
  ALSA: sb: Convert to copy_silence ops
  ALSA: sh: Convert to copy_silence ops
  ASoC: blackfin: Convert to copy_silence ops
  [media] solo6x10: Convert to copy_silence ops
  ALSA: pcm: Drop the old copy and silence ops

 .../sound/kernel-api/writing-an-alsa-driver.rst    | 110 ++++++++++--------
 drivers/media/pci/solo6x10/solo6x10-g723.c         |  13 ++-
 include/sound/pcm.h                                |   8 +-
 sound/core/pcm_lib.c                               |  68 ++++++-----
 sound/drivers/dummy.c                              |  13 +--
 sound/isa/gus/gus_pcm.c                            |  43 ++-----
 sound/isa/sb/emu8000_pcm.c                         |  99 +++++-----------
 sound/pci/es1938.c                                 |  11 +-
 sound/pci/korg1212/korg1212.c                      | 128 ++++++---------------
 sound/pci/nm256/nm256.c                            |  35 +++---
 sound/pci/rme32.c                                  |  49 ++++----
 sound/pci/rme96.c                                  |  52 ++++-----
 sound/pci/rme9652/hdsp.c                           |  44 ++++---
 sound/pci/rme9652/rme9652.c                        |  46 ++++----
 sound/sh/sh_dac_audio.c                            |  40 ++-----
 sound/soc/blackfin/bf5xx-ac97-pcm.c                |   6 +-
 sound/soc/blackfin/bf5xx-ac97.c                    |  18 ++-
 sound/soc/blackfin/bf5xx-i2s-pcm.c                 |  46 +++-----
 sound/soc/soc-pcm.c                                |   3 +-
 19 files changed, 340 insertions(+), 492 deletions(-)

-- 
2.13.0

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 01/16] ALSA: pcm: Introduce copy_silence PCM ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
@ 2017-05-21 20:09   ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 02/16] ALSA: Update document about " Takashi Iwai
                     ` (14 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

For supporting the explicit in-kernel copy of PCM buffer data, and
also for reducing the redundant codes for both PCM copy and silence
callbacks, a new ops copy_silence is introduced in this patch.  This
is supposed to serve for both copy and silence operations.  The
silence operation is distinguished by NULL buffer passed (required
only in playback direction).

Also, the callback receives a new boolean flag, in_kernel, which
indicates that the callback gets called for copying the data from/to
the kernel buffer instead of the user-space buffer.  The in_kernel
flag will be used mainly in PCM OSS code for the on-the-fly
conversion.  As this patch stands, only in_kernel=false is passed.
The actual usage of in_kernel=true will be introduced later.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/sound/pcm.h  |  3 +++
 sound/core/pcm_lib.c | 74 +++++++++++++++++++++++++++++++++++++++++-----------
 sound/soc/soc-pcm.c  |  1 +
 3 files changed, 63 insertions(+), 15 deletions(-)

diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index c609b891c4c2..b9dd813dd885 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -83,6 +83,9 @@ struct snd_pcm_ops {
 		    void __user *buf, snd_pcm_uframes_t count);
 	int (*silence)(struct snd_pcm_substream *substream, int channel, 
 		       snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
+	int (*copy_silence)(struct snd_pcm_substream *substream, int channel,
+			    snd_pcm_uframes_t pos, void __user *buf,
+			    snd_pcm_uframes_t count, bool in_kernel);
 	struct page *(*page)(struct snd_pcm_substream *substream,
 			     unsigned long offset);
 	int (*mmap)(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index ab4b1d1e44ee..b720cbda017f 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -55,6 +55,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t frames, ofs, transfer;
+	char *hwbuf;
+	int err;
 
 	if (runtime->silence_size < runtime->boundary) {
 		snd_pcm_sframes_t noise_dist, n;
@@ -109,27 +111,35 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
 		transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;
 		if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
 		    runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
-			if (substream->ops->silence) {
-				int err;
+			if (substream->ops->copy_silence) {
+				err = substream->ops->copy_silence(substream,
+					-1, ofs, NULL, transfer, false);
+				snd_BUG_ON(err < 0);
+			} else if (substream->ops->silence) {
 				err = substream->ops->silence(substream, -1, ofs, transfer);
 				snd_BUG_ON(err < 0);
 			} else {
-				char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs);
+				hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs);
 				snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels);
 			}
 		} else {
 			unsigned int c;
 			unsigned int channels = runtime->channels;
-			if (substream->ops->silence) {
+			if (substream->ops->copy_silence) {
+				for (c = 0; c < channels; ++c) {
+					err = substream->ops->copy_silence(substream,
+						c, ofs, NULL, transfer, false);
+					snd_BUG_ON(err < 0);
+				}
+			} else if (substream->ops->silence) {
 				for (c = 0; c < channels; ++c) {
-					int err;
 					err = substream->ops->silence(substream, c, ofs, transfer);
 					snd_BUG_ON(err < 0);
 				}
 			} else {
 				size_t dma_csize = runtime->dma_bytes / channels;
 				for (c = 0; c < channels; ++c) {
-					char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, ofs);
+					hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, ofs);
 					snd_pcm_format_set_silence(runtime->format, hwbuf, transfer);
 				}
 			}
@@ -1995,7 +2005,12 @@ static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
-	if (substream->ops->copy) {
+	if (substream->ops->copy_silence) {
+		err = substream->ops->copy_silence(substream, -1, hwoff, buf,
+						   frames, false);
+		if (err < 0)
+			return err;
+	} else if (substream->ops->copy) {
 		if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
 			return err;
 	} else {
@@ -2119,7 +2134,8 @@ static int pcm_sanity_check(struct snd_pcm_substream *substream)
 	if (PCM_RUNTIME_CHECK(substream))
 		return -ENXIO;
 	runtime = substream->runtime;
-	if (snd_BUG_ON(!substream->ops->copy && !runtime->dma_area))
+	if (snd_BUG_ON(!substream->ops->copy_silence && !substream->ops->copy
+		       && !runtime->dma_area))
 		return -EINVAL;
 	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
 		return -EBADFD;
@@ -2156,8 +2172,21 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
 	int err;
 	void __user **bufs = (void __user **)data;
 	int channels = runtime->channels;
+	char __user *buf;
 	int c;
-	if (substream->ops->copy) {
+
+	if (substream->ops->copy_silence) {
+		for (c = 0; c < channels; ++c, ++bufs) {
+			if (!*bufs)
+				buf = NULL;
+			else
+				buf = *bufs + samples_to_bytes(runtime, off);
+			err = substream->ops->copy_silence(substream, c, hwoff,
+							   buf, frames, false);
+			if (err < 0)
+				return err;
+		}
+	} else if (substream->ops->copy) {
 		if (snd_BUG_ON(!substream->ops->silence))
 			return -EINVAL;
 		for (c = 0; c < channels; ++c, ++bufs) {
@@ -2165,7 +2194,7 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
 				if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0)
 					return err;
 			} else {
-				char __user *buf = *bufs + samples_to_bytes(runtime, off);
+				buf = *bufs + samples_to_bytes(runtime, off);
 				if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0)
 					return err;
 			}
@@ -2217,7 +2246,12 @@ static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
-	if (substream->ops->copy) {
+	if (substream->ops->copy_silence) {
+		err = substream->ops->copy_silence(substream, -1, hwoff, buf,
+						   frames, false);
+		if (err < 0)
+			return err;
+	} else if (substream->ops->copy) {
 		if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
 			return err;
 	} else {
@@ -2365,10 +2399,22 @@ static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
 	int err;
 	void __user **bufs = (void __user **)data;
 	int channels = runtime->channels;
+	char __user *buf;
+	char *hwbuf;
 	int c;
-	if (substream->ops->copy) {
+
+	if (substream->ops->copy_silence) {
+		for (c = 0; c < channels; ++c, ++bufs) {
+			if (!*bufs)
+				continue;
+			buf = *bufs + samples_to_bytes(runtime, off);
+			err = substream->ops->copy_silence(substream, c, hwoff,
+							   buf, frames, false);
+			if (err < 0)
+				return err;
+		}
+	} else if (substream->ops->copy) {
 		for (c = 0; c < channels; ++c, ++bufs) {
-			char __user *buf;
 			if (*bufs == NULL)
 				continue;
 			buf = *bufs + samples_to_bytes(runtime, off);
@@ -2378,8 +2424,6 @@ static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
 	} else {
 		snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels;
 		for (c = 0; c < channels; ++c, ++bufs) {
-			char *hwbuf;
-			char __user *buf;
 			if (*bufs == NULL)
 				continue;
 
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index efc5831f205d..3cfb9aa1203b 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -2743,6 +2743,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
 
 	if (platform->driver->ops) {
 		rtd->ops.ack		= platform->driver->ops->ack;
+		rtd->ops.copy_silence	= platform->driver->ops->copy_silence;
 		rtd->ops.copy		= platform->driver->ops->copy;
 		rtd->ops.silence	= platform->driver->ops->silence;
 		rtd->ops.page		= platform->driver->ops->page;
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 01/16] ALSA: pcm: Introduce copy_silence PCM ops
@ 2017-05-21 20:09   ` Takashi Iwai
  0 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Mark Brown, Bluecherry Maintainers, linux-media, Takashi Sakamoto

For supporting the explicit in-kernel copy of PCM buffer data, and
also for reducing the redundant codes for both PCM copy and silence
callbacks, a new ops copy_silence is introduced in this patch.  This
is supposed to serve for both copy and silence operations.  The
silence operation is distinguished by NULL buffer passed (required
only in playback direction).

Also, the callback receives a new boolean flag, in_kernel, which
indicates that the callback gets called for copying the data from/to
the kernel buffer instead of the user-space buffer.  The in_kernel
flag will be used mainly in PCM OSS code for the on-the-fly
conversion.  As this patch stands, only in_kernel=false is passed.
The actual usage of in_kernel=true will be introduced later.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/sound/pcm.h  |  3 +++
 sound/core/pcm_lib.c | 74 +++++++++++++++++++++++++++++++++++++++++-----------
 sound/soc/soc-pcm.c  |  1 +
 3 files changed, 63 insertions(+), 15 deletions(-)

diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index c609b891c4c2..b9dd813dd885 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -83,6 +83,9 @@ struct snd_pcm_ops {
 		    void __user *buf, snd_pcm_uframes_t count);
 	int (*silence)(struct snd_pcm_substream *substream, int channel, 
 		       snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
+	int (*copy_silence)(struct snd_pcm_substream *substream, int channel,
+			    snd_pcm_uframes_t pos, void __user *buf,
+			    snd_pcm_uframes_t count, bool in_kernel);
 	struct page *(*page)(struct snd_pcm_substream *substream,
 			     unsigned long offset);
 	int (*mmap)(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index ab4b1d1e44ee..b720cbda017f 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -55,6 +55,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t frames, ofs, transfer;
+	char *hwbuf;
+	int err;
 
 	if (runtime->silence_size < runtime->boundary) {
 		snd_pcm_sframes_t noise_dist, n;
@@ -109,27 +111,35 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
 		transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;
 		if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
 		    runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
-			if (substream->ops->silence) {
-				int err;
+			if (substream->ops->copy_silence) {
+				err = substream->ops->copy_silence(substream,
+					-1, ofs, NULL, transfer, false);
+				snd_BUG_ON(err < 0);
+			} else if (substream->ops->silence) {
 				err = substream->ops->silence(substream, -1, ofs, transfer);
 				snd_BUG_ON(err < 0);
 			} else {
-				char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs);
+				hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs);
 				snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels);
 			}
 		} else {
 			unsigned int c;
 			unsigned int channels = runtime->channels;
-			if (substream->ops->silence) {
+			if (substream->ops->copy_silence) {
+				for (c = 0; c < channels; ++c) {
+					err = substream->ops->copy_silence(substream,
+						c, ofs, NULL, transfer, false);
+					snd_BUG_ON(err < 0);
+				}
+			} else if (substream->ops->silence) {
 				for (c = 0; c < channels; ++c) {
-					int err;
 					err = substream->ops->silence(substream, c, ofs, transfer);
 					snd_BUG_ON(err < 0);
 				}
 			} else {
 				size_t dma_csize = runtime->dma_bytes / channels;
 				for (c = 0; c < channels; ++c) {
-					char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, ofs);
+					hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, ofs);
 					snd_pcm_format_set_silence(runtime->format, hwbuf, transfer);
 				}
 			}
@@ -1995,7 +2005,12 @@ static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
-	if (substream->ops->copy) {
+	if (substream->ops->copy_silence) {
+		err = substream->ops->copy_silence(substream, -1, hwoff, buf,
+						   frames, false);
+		if (err < 0)
+			return err;
+	} else if (substream->ops->copy) {
 		if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
 			return err;
 	} else {
@@ -2119,7 +2134,8 @@ static int pcm_sanity_check(struct snd_pcm_substream *substream)
 	if (PCM_RUNTIME_CHECK(substream))
 		return -ENXIO;
 	runtime = substream->runtime;
-	if (snd_BUG_ON(!substream->ops->copy && !runtime->dma_area))
+	if (snd_BUG_ON(!substream->ops->copy_silence && !substream->ops->copy
+		       && !runtime->dma_area))
 		return -EINVAL;
 	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
 		return -EBADFD;
@@ -2156,8 +2172,21 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
 	int err;
 	void __user **bufs = (void __user **)data;
 	int channels = runtime->channels;
+	char __user *buf;
 	int c;
-	if (substream->ops->copy) {
+
+	if (substream->ops->copy_silence) {
+		for (c = 0; c < channels; ++c, ++bufs) {
+			if (!*bufs)
+				buf = NULL;
+			else
+				buf = *bufs + samples_to_bytes(runtime, off);
+			err = substream->ops->copy_silence(substream, c, hwoff,
+							   buf, frames, false);
+			if (err < 0)
+				return err;
+		}
+	} else if (substream->ops->copy) {
 		if (snd_BUG_ON(!substream->ops->silence))
 			return -EINVAL;
 		for (c = 0; c < channels; ++c, ++bufs) {
@@ -2165,7 +2194,7 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
 				if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0)
 					return err;
 			} else {
-				char __user *buf = *bufs + samples_to_bytes(runtime, off);
+				buf = *bufs + samples_to_bytes(runtime, off);
 				if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0)
 					return err;
 			}
@@ -2217,7 +2246,12 @@ static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
-	if (substream->ops->copy) {
+	if (substream->ops->copy_silence) {
+		err = substream->ops->copy_silence(substream, -1, hwoff, buf,
+						   frames, false);
+		if (err < 0)
+			return err;
+	} else if (substream->ops->copy) {
 		if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
 			return err;
 	} else {
@@ -2365,10 +2399,22 @@ static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
 	int err;
 	void __user **bufs = (void __user **)data;
 	int channels = runtime->channels;
+	char __user *buf;
+	char *hwbuf;
 	int c;
-	if (substream->ops->copy) {
+
+	if (substream->ops->copy_silence) {
+		for (c = 0; c < channels; ++c, ++bufs) {
+			if (!*bufs)
+				continue;
+			buf = *bufs + samples_to_bytes(runtime, off);
+			err = substream->ops->copy_silence(substream, c, hwoff,
+							   buf, frames, false);
+			if (err < 0)
+				return err;
+		}
+	} else if (substream->ops->copy) {
 		for (c = 0; c < channels; ++c, ++bufs) {
-			char __user *buf;
 			if (*bufs == NULL)
 				continue;
 			buf = *bufs + samples_to_bytes(runtime, off);
@@ -2378,8 +2424,6 @@ static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
 	} else {
 		snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels;
 		for (c = 0; c < channels; ++c, ++bufs) {
-			char *hwbuf;
-			char __user *buf;
 			if (*bufs == NULL)
 				continue;
 
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index efc5831f205d..3cfb9aa1203b 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -2743,6 +2743,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
 
 	if (platform->driver->ops) {
 		rtd->ops.ack		= platform->driver->ops->ack;
+		rtd->ops.copy_silence	= platform->driver->ops->copy_silence;
 		rtd->ops.copy		= platform->driver->ops->copy;
 		rtd->ops.silence	= platform->driver->ops->silence;
 		rtd->ops.page		= platform->driver->ops->page;
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 02/16] ALSA: Update document about copy_silence PCM ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
  2017-05-21 20:09   ` Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 03/16] ALSA: dummy: Convert to copy_silence ops Takashi Iwai
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 .../sound/kernel-api/writing-an-alsa-driver.rst    | 110 ++++++++++++---------
 1 file changed, 63 insertions(+), 47 deletions(-)

diff --git a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
index 95c5443eff38..ebaf8b1e0079 100644
--- a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
+++ b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
@@ -2080,18 +2080,18 @@ sleeping poll threads, etc.
 
 This callback is also atomic as default.
 
-copy and silence callbacks
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+copy_silence callback
+~~~~~~~~~~~~~~~~~~~~~
 
-These callbacks are not mandatory, and can be omitted in most cases.
-These callbacks are used when the hardware buffer cannot be in the
+This callback is not mandatory, and can be omitted in most cases.
+This callback is used when the hardware buffer cannot be in the
 normal memory space. Some chips have their own buffer on the hardware
 which is not mappable. In such a case, you have to transfer the data
 manually from the memory buffer to the hardware buffer. Or, if the
 buffer is non-contiguous on both physical and virtual memory spaces,
 these callbacks must be defined, too.
 
-If these two callbacks are defined, copy and set-silence operations
+If this callback is defined, copy and set-silence operations
 are done by them. The detailed will be described in the later section
 `Buffer and Memory Management`_.
 
@@ -3545,30 +3545,34 @@ Another case is when the chip uses a PCI memory-map region for the
 buffer instead of the host memory. In this case, mmap is available only
 on certain architectures like the Intel one. In non-mmap mode, the data
 cannot be transferred as in the normal way. Thus you need to define the
-``copy`` and ``silence`` callbacks as well, as in the cases above. The
+``copy_silence`` callback as well, as in the cases above. The
 examples are found in ``rme32.c`` and ``rme96.c``.
 
-The implementation of the ``copy`` and ``silence`` callbacks depends
+The implementation of the ``copy_silence`` callback depends
 upon whether the hardware supports interleaved or non-interleaved
-samples. The ``copy`` callback is defined like below, a bit
+samples. The ``copy_silence`` callback is defined like below, a bit
 differently depending whether the direction is playback or capture:
 
 ::
 
   static int playback_copy(struct snd_pcm_substream *substream, int channel,
-               snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count);
+               snd_pcm_uframes_t pos, void __user *src,
+	       snd_pcm_uframes_t count, bool in_kernel);
   static int capture_copy(struct snd_pcm_substream *substream, int channel,
-               snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count);
+               snd_pcm_uframes_t pos, void __user *dst,
+	       snd_pcm_uframes_t count, bool in_kernel);
 
 In the case of interleaved samples, the second argument (``channel``) is
-not used. The third argument (``pos``) points the current position
-offset in frames.
+not used, and -1 is passed. The third argument (``pos``) points the
+current position offset in frames.
 
 The meaning of the fourth argument is different between playback and
 capture. For playback, it holds the source data pointer, and for
 capture, it's the destination data pointer.
 
-The last argument is the number of frames to be copied.
+The fifth argument is the number of frames to be copied.
+And the last argument indicates whether the passed buffer pointer is in
+user-space or in kernel-space.  The copy operation depends on this.
 
 What you have to do in this callback is again different between playback
 and capture directions. In the playback case, you copy the given amount
@@ -3578,52 +3582,64 @@ way, the copy would be like:
 
 ::
 
-  my_memcpy(my_buffer + frames_to_bytes(runtime, pos), src,
-            frames_to_bytes(runtime, count));
-
-For the capture direction, you copy the given amount of data (``count``)
-at the specified offset (``pos``) on the hardware buffer to the
-specified pointer (``dst``).
-
-::
+  if (!src)
+          my_memset(my_buffer + frames_to_bytes(runtime, pos), 0,
+                    frames_to_bytes(runtime, count));
+  else if (in_kernel)
+          memcpy_toio(my_buffer + frames_to_bytes(runtime, pos),
+                      (void *)src, frames_to_bytes(runtime, count));
+  else if (copy_from_user_toio(my_buffer + frames_to_bytes(runtime, pos),
+                               src, frames_to_bytes(runtime, count)))
+          return -EFAULT;
+  return 0;
 
-  my_memcpy(dst, my_buffer + frames_to_bytes(runtime, pos),
-            frames_to_bytes(runtime, count));
+Here we prepared three different memory operations operations.
 
-Note that both the position and the amount of data are given in frames.
+The first one, with the NULL ``src`` pointer, is for silencing the
+buffer. In this case, we clear the samples for the given position and
+portion.
 
-In the case of non-interleaved samples, the implementation will be a bit
-more complicated.
+The second one, with ``in_kernel`` check, is for the in-kernel memory
+copying.  In this case, the given buffer pointer (``src``) is a kernel
+pointer despite of being declared with ``__user`` prefix.  When this
+flag is set, you have to copy the memory from the kernel space.
+Typically, a simple :c:func:`memcpy()` or :c:func`memcpy_toio()` can
+be used.  Note the explicit cast at the function call there to drop
+``__user`` prefix.
 
-You need to check the channel argument, and if it's -1, copy the whole
-channels. Otherwise, you have to copy only the specified channel. Please
-check ``isa/gus/gus_pcm.c`` as an example.
+The last one is the usual operation, to copy from the user-space
+buffer to the hardware buffer.
 
-The ``silence`` callback is also implemented in a similar way
+For the capture direction, you copy the given amount of data (``count``)
+at the specified offset (``pos``) on the hardware buffer to the
+specified pointer (``dst``).
 
 ::
 
-  static int silence(struct snd_pcm_substream *substream, int channel,
-                     snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
-
-The meanings of arguments are the same as in the ``copy`` callback,
-although there is no ``src/dst`` argument. In the case of interleaved
-samples, the channel argument has no meaning, as well as on ``copy``
-callback.
+  if (in_kernel)
+          memcpy_fromio((void *)dst,
+	          my_buffer + frames_to_bytes(runtime, pos),
+                  frames_to_bytes(runtime, count));
+  else if (copy_to_user_fromio(dst,
+                  my_buffer + frames_to_bytes(runtime, pos),
+                  frames_to_bytes(runtime, count)))
+          return -EFAULT;
+  return 0;
 
-The role of ``silence`` callback is to set the given amount
-(``count``) of silence data at the specified offset (``pos``) on the
-hardware buffer. Suppose that the data format is signed (that is, the
-silent-data is 0), and the implementation using a memset-like function
-would be like: 
+A clear difference from the playback is that there is no silencing
+mode.  For the capture direction, ``dst`` is always non-NULL.
 
-::
+Other than that, the two memory operations are similar, but just in
+different direction.  And, note that both the position and the amount
+of data are given in frames.
 
-  my_memcpy(my_buffer + frames_to_bytes(runtime, pos), 0,
-            frames_to_bytes(runtime, count));
+In the case of non-interleaved samples, the implementation will be a bit
+more complicated.  First off, the operation depends on ``channel``
+argument.  When -1 is passed there, copy the whole channels.
+Otherwise, copy only the specified channel.
 
-In the case of non-interleaved samples, again, the implementation
-becomes a bit more complicated. See, for example, ``isa/gus/gus_pcm.c``.
+As an implementation example, please take a look at the code in
+``sound/isa/gus/gus_pcm.c``.
 
 Non-Contiguous Buffers
 ----------------------
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 03/16] ALSA: dummy: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
  2017-05-21 20:09   ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 02/16] ALSA: Update document about " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 04/16] ALSA: es1938: " Takashi Iwai
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

It's a dummy ops, so just replacing it.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/drivers/dummy.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 172dacd925f5..68519689a9ea 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -645,14 +645,8 @@ static int alloc_fake_buffer(void)
 
 static int dummy_pcm_copy(struct snd_pcm_substream *substream,
 			  int channel, snd_pcm_uframes_t pos,
-			  void __user *dst, snd_pcm_uframes_t count)
-{
-	return 0; /* do nothing */
-}
-
-static int dummy_pcm_silence(struct snd_pcm_substream *substream,
-			     int channel, snd_pcm_uframes_t pos,
-			     snd_pcm_uframes_t count)
+			  void __user *dst, snd_pcm_uframes_t count,
+			  bool in_kernel)
 {
 	return 0; /* do nothing */
 }
@@ -683,8 +677,7 @@ static struct snd_pcm_ops dummy_pcm_ops_no_buf = {
 	.prepare =	dummy_pcm_prepare,
 	.trigger =	dummy_pcm_trigger,
 	.pointer =	dummy_pcm_pointer,
-	.copy =		dummy_pcm_copy,
-	.silence =	dummy_pcm_silence,
+	.copy_silence =	dummy_pcm_copy,
 	.page =		dummy_pcm_page,
 };
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 04/16] ALSA: es1938: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (2 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 03/16] ALSA: dummy: Convert to copy_silence ops Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 05/16] ALSA: korg1212: " Takashi Iwai
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
It's used only for a capture stream (for some hardware workaround),
thus we need no silence operation but only to add the in_kernel
memcpy() handling.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/es1938.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index e8d943071a8c..d79ac13d6f70 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -842,7 +842,8 @@ static int snd_es1938_capture_copy(struct snd_pcm_substream *substream,
 				   int channel,
 				   snd_pcm_uframes_t pos,
 				   void __user *dst,
-				   snd_pcm_uframes_t count)
+				   snd_pcm_uframes_t count,
+				   bool in_kernel)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct es1938 *chip = snd_pcm_substream_chip(substream);
@@ -850,8 +851,10 @@ static int snd_es1938_capture_copy(struct snd_pcm_substream *substream,
 	count <<= chip->dma1_shift;
 	if (snd_BUG_ON(pos + count > chip->dma1_size))
 		return -EINVAL;
-	if (pos + count < chip->dma1_size) {
-		if (copy_to_user(dst, runtime->dma_area + pos + 1, count))
+	if (in_kernel || pos + count < chip->dma1_size) {
+		if (in_kernel)
+			memcpy((void *)dst, runtime->dma_area + pos + 1, count);
+		else if (copy_to_user(dst, runtime->dma_area + pos + 1, count))
 			return -EFAULT;
 	} else {
 		if (copy_to_user(dst, runtime->dma_area + pos + 1, count - 1))
@@ -1012,7 +1015,7 @@ static const struct snd_pcm_ops snd_es1938_capture_ops = {
 	.prepare =	snd_es1938_capture_prepare,
 	.trigger =	snd_es1938_capture_trigger,
 	.pointer =	snd_es1938_capture_pointer,
-	.copy =		snd_es1938_capture_copy,
+	.copy_silence =	snd_es1938_capture_copy,
 };
 
 static int snd_es1938_new_pcm(struct es1938 *chip, int device)
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 05/16] ALSA: korg1212: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (3 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 04/16] ALSA: es1938: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 06/16] ALSA: nm256: " Takashi Iwai
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
The redundant function calls are reduced and the copy/silence are
handled directly in callback functions now.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/korg1212/korg1212.c | 128 ++++++++++++------------------------------
 1 file changed, 36 insertions(+), 92 deletions(-)

diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 1e25095fd144..865ff553dc87 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -1273,43 +1273,24 @@ static struct snd_pcm_hardware snd_korg1212_capture_info =
         .fifo_size =          0,
 };
 
-static int snd_korg1212_silence(struct snd_korg1212 *korg1212, int pos, int count, int offset, int size)
-{
-	struct KorgAudioFrame * dst =  korg1212->playDataBufsPtr[0].bufferData + pos;
-	int i;
-
-	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n",
-				   pos, offset, size, count);
-	if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
-		return -EINVAL;
-
-	for (i=0; i < count; i++) {
-#if K1212_DEBUG_LEVEL > 0
-		if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
-		     (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
-			printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_silence KERNEL EFAULT dst=%p iter=%d\n",
-			       dst, i);
-			return -EFAULT;
-		}
-#endif
-		memset((void*) dst + offset, 0, size);
-		dst++;
-	}
-
-	return 0;
-}
-
-static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst, int pos, int count, int offset, int size)
+static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream,
+				     int channel,
+				     snd_pcm_uframes_t pos,
+				     void __user *dst,
+				     snd_pcm_uframes_t count,
+				     bool in_kernel)
 {
+	struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
 	struct KorgAudioFrame * src =  korg1212->recordDataBufsPtr[0].bufferData + pos;
-	int i, rc;
+	int size, i;
 
-	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n",
-				   pos, offset, size);
+	size = korg1212->channels * 2;
+	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%ld size=%d\n",
+				   pos, size);
 	if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
 		return -EINVAL;
 
-	for (i=0; i < count; i++) {
+	for (i = 0; i < count; i++) {
 #if K1212_DEBUG_LEVEL > 0
 		if ( (void *) src < (void *) korg1212->recordDataBufsPtr ||
 		     (void *) src > (void *) korg1212->recordDataBufsPtr[8].bufferData ) {
@@ -1317,11 +1298,10 @@ static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst,
 			return -EFAULT;
 		}
 #endif
-		rc = copy_to_user(dst + offset, src, size);
-		if (rc) {
-			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
+		if (in_kernel)
+			memcpy((char *)dst, src, size);
+		else if (copy_to_user(dst, src, size))
 			return -EFAULT;
-		}
 		src++;
 		dst += size;
 	}
@@ -1329,18 +1309,25 @@ static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst,
 	return 0;
 }
 
-static int snd_korg1212_copy_from(struct snd_korg1212 *korg1212, void __user *src, int pos, int count, int offset, int size)
+static int snd_korg1212_playback_copy(struct snd_pcm_substream *substream,
+				      int channel,
+				      snd_pcm_uframes_t pos,
+				      void __user *src,
+				      snd_pcm_uframes_t count,
+				      bool in_kernel)
 {
+	struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
 	struct KorgAudioFrame * dst =  korg1212->playDataBufsPtr[0].bufferData + pos;
-	int i, rc;
+	int size, i;
 
-	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n",
-				   pos, offset, size, count);
+	size = korg1212->channels * 2;
+	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%ld size=%d count=%ld\n",
+				   pos, size, count);
 
 	if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
 		return -EINVAL;
 
-	for (i=0; i < count; i++) {
+	for (i = 0; i < count; i++) {
 #if K1212_DEBUG_LEVEL > 0
 		if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
 		     (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
@@ -1348,13 +1335,15 @@ static int snd_korg1212_copy_from(struct snd_korg1212 *korg1212, void __user *sr
 			return -EFAULT;
 		}
 #endif
-		rc = copy_from_user((void*) dst + offset, src, size);
-		if (rc) {
-			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
+		if (!src)
+			memset((void *)dst, 0, size);
+		else if (in_kernel)
+			memcpy((void *)dst, src, size);
+		else if (copy_from_user((void *)dst, src, size))
 			return -EFAULT;
-		}
 		dst++;
-		src += size;
+		if (src)
+			src += size;
 	}
 
 	return 0;
@@ -1437,8 +1426,6 @@ static int snd_korg1212_playback_close(struct snd_pcm_substream *substream)
 	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_close [%s]\n",
 			   stateName[korg1212->cardState]);
 
-	snd_korg1212_silence(korg1212, 0, K1212_MAX_SAMPLES, 0, korg1212->channels * 2);
-
         spin_lock_irqsave(&korg1212->lock, flags);
 
 	korg1212->playback_pid = -1;
@@ -1639,48 +1626,6 @@ static snd_pcm_uframes_t snd_korg1212_capture_pointer(struct snd_pcm_substream *
         return pos;
 }
 
-static int snd_korg1212_playback_copy(struct snd_pcm_substream *substream,
-                        int channel, /* not used (interleaved data) */
-                        snd_pcm_uframes_t pos,
-                        void __user *src,
-                        snd_pcm_uframes_t count)
-{
-        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
-
-	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_copy [%s] %ld %ld\n",
-				   stateName[korg1212->cardState], pos, count);
- 
-	return snd_korg1212_copy_from(korg1212, src, pos, count, 0, korg1212->channels * 2);
-
-}
-
-static int snd_korg1212_playback_silence(struct snd_pcm_substream *substream,
-                           int channel, /* not used (interleaved data) */
-                           snd_pcm_uframes_t pos,
-                           snd_pcm_uframes_t count)
-{
-        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
-
-	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_silence [%s]\n",
-				   stateName[korg1212->cardState]);
-
-	return snd_korg1212_silence(korg1212, pos, count, 0, korg1212->channels * 2);
-}
-
-static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream,
-                        int channel, /* not used (interleaved data) */
-                        snd_pcm_uframes_t pos,
-                        void __user *dst,
-                        snd_pcm_uframes_t count)
-{
-        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
-
-	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_capture_copy [%s] %ld %ld\n",
-				   stateName[korg1212->cardState], pos, count);
-
-	return snd_korg1212_copy_to(korg1212, dst, pos, count, 0, korg1212->channels * 2);
-}
-
 static const struct snd_pcm_ops snd_korg1212_playback_ops = {
         .open =		snd_korg1212_playback_open,
         .close =	snd_korg1212_playback_close,
@@ -1689,8 +1634,7 @@ static const struct snd_pcm_ops snd_korg1212_playback_ops = {
         .prepare =	snd_korg1212_prepare,
         .trigger =	snd_korg1212_trigger,
         .pointer =	snd_korg1212_playback_pointer,
-        .copy =		snd_korg1212_playback_copy,
-        .silence =	snd_korg1212_playback_silence,
+	.copy_silence =	snd_korg1212_playback_copy,
 };
 
 static const struct snd_pcm_ops snd_korg1212_capture_ops = {
@@ -1701,7 +1645,7 @@ static const struct snd_pcm_ops snd_korg1212_capture_ops = {
 	.prepare =	snd_korg1212_prepare,
 	.trigger =	snd_korg1212_trigger,
 	.pointer =	snd_korg1212_capture_pointer,
-	.copy =		snd_korg1212_capture_copy,
+	.copy_silence =	snd_korg1212_capture_copy,
 };
 
 /*
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 06/16] ALSA: nm256: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (4 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 05/16] ALSA: korg1212: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 07/16] ALSA: rme32: " Takashi Iwai
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
The conversion is straightforward with standard helper functions.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/nm256/nm256.c | 35 ++++++++++++++---------------------
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 103fe311e5a9..d8e765f7e758 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -694,31 +694,22 @@ snd_nm256_capture_pointer(struct snd_pcm_substream *substream)
  * silence / copy for playback
  */
 static int
-snd_nm256_playback_silence(struct snd_pcm_substream *substream,
-			   int channel, /* not used (interleaved data) */
-			   snd_pcm_uframes_t pos,
-			   snd_pcm_uframes_t count)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct nm256_stream *s = runtime->private_data;
-	count = frames_to_bytes(runtime, count);
-	pos = frames_to_bytes(runtime, pos);
-	memset_io(s->bufptr + pos, 0, count);
-	return 0;
-}
-
-static int
 snd_nm256_playback_copy(struct snd_pcm_substream *substream,
 			int channel, /* not used (interleaved data) */
 			snd_pcm_uframes_t pos,
 			void __user *src,
-			snd_pcm_uframes_t count)
+			snd_pcm_uframes_t count,
+			bool in_kernel)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct nm256_stream *s = runtime->private_data;
 	count = frames_to_bytes(runtime, count);
 	pos = frames_to_bytes(runtime, pos);
-	if (copy_from_user_toio(s->bufptr + pos, src, count))
+	if (!src)
+		memset_io(s->bufptr + pos, 0, count);
+	else if (in_kernel)
+		memcpy_toio(s->bufptr + pos, (void *)src, count);
+	else if (copy_from_user_toio(s->bufptr + pos, src, count))
 		return -EFAULT;
 	return 0;
 }
@@ -731,13 +722,16 @@ snd_nm256_capture_copy(struct snd_pcm_substream *substream,
 		       int channel, /* not used (interleaved data) */
 		       snd_pcm_uframes_t pos,
 		       void __user *dst,
-		       snd_pcm_uframes_t count)
+		       snd_pcm_uframes_t count,
+		       bool in_kernel)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct nm256_stream *s = runtime->private_data;
 	count = frames_to_bytes(runtime, count);
 	pos = frames_to_bytes(runtime, pos);
-	if (copy_to_user_fromio(dst, s->bufptr + pos, count))
+	if (in_kernel)
+		memcpy_fromio((void *)dst, s->bufptr + pos, count);
+	else if (copy_to_user_fromio(dst, s->bufptr + pos, count))
 		return -EFAULT;
 	return 0;
 }
@@ -911,8 +905,7 @@ static const struct snd_pcm_ops snd_nm256_playback_ops = {
 	.trigger =	snd_nm256_playback_trigger,
 	.pointer =	snd_nm256_playback_pointer,
 #ifndef __i386__
-	.copy =		snd_nm256_playback_copy,
-	.silence =	snd_nm256_playback_silence,
+	.copy_silence =	snd_nm256_playback_copy,
 #endif
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
@@ -926,7 +919,7 @@ static const struct snd_pcm_ops snd_nm256_capture_ops = {
 	.trigger =	snd_nm256_capture_trigger,
 	.pointer =	snd_nm256_capture_pointer,
 #ifndef __i386__
-	.copy =		snd_nm256_capture_copy,
+	.copy_silence =	snd_nm256_capture_copy,
 #endif
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 07/16] ALSA: rme32: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (5 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 06/16] ALSA: nm256: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 08/16] ALSA: rme96: " Takashi Iwai
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
The conversion is straightforward with standard helper functions.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/rme32.c | 49 ++++++++++++++++++++++++-------------------------
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 96d15db65dfd..d2b4a3ef0bd3 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -253,41 +253,42 @@ static inline unsigned int snd_rme32_pcm_byteptr(struct rme32 * rme32)
 		& RME32_RCR_AUDIO_ADDR_MASK);
 }
 
-/* silence callback for halfduplex mode */
-static int snd_rme32_playback_silence(struct snd_pcm_substream *substream, int channel,	/* not used (interleaved data) */
-				      snd_pcm_uframes_t pos,
-				      snd_pcm_uframes_t count)
-{
-	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
-	count <<= rme32->playback_frlog;
-	pos <<= rme32->playback_frlog;
-	memset_io(rme32->iobase + RME32_IO_DATA_BUFFER + pos, 0, count);
-	return 0;
-}
-
 /* copy callback for halfduplex mode */
-static int snd_rme32_playback_copy(struct snd_pcm_substream *substream, int channel,	/* not used (interleaved data) */
+static int snd_rme32_playback_copy(struct snd_pcm_substream *substream,
+				   int channel,	/* not used (interleaved data) */
 				   snd_pcm_uframes_t pos,
-				   void __user *src, snd_pcm_uframes_t count)
+				   void __user *src, snd_pcm_uframes_t count,
+				   bool in_kernel)
 {
 	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	count <<= rme32->playback_frlog;
 	pos <<= rme32->playback_frlog;
-	if (copy_from_user_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos,
-			    src, count))
+	if (!src)
+		memset_io(rme32->iobase + RME32_IO_DATA_BUFFER + pos, 0, count);
+	else if (in_kernel)
+		memcpy_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos,
+			    (void *)src, count);
+	else if (copy_from_user_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos,
+				     src, count))
 		return -EFAULT;
 	return 0;
 }
 
 /* copy callback for halfduplex mode */
-static int snd_rme32_capture_copy(struct snd_pcm_substream *substream, int channel,	/* not used (interleaved data) */
+static int snd_rme32_capture_copy(struct snd_pcm_substream *substream,
+				  int channel,	/* not used (interleaved data) */
 				  snd_pcm_uframes_t pos,
-				  void __user *dst, snd_pcm_uframes_t count)
+				  void __user *dst, snd_pcm_uframes_t count,
+				  bool in_kernel)
 {
 	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	count <<= rme32->capture_frlog;
 	pos <<= rme32->capture_frlog;
-	if (copy_to_user_fromio(dst,
+	if (in_kernel)
+		memcpy_fromio((void *)dst,
+			      rme32->iobase + RME32_IO_DATA_BUFFER + pos,
+			      count);
+	else if (copy_to_user_fromio(dst,
 			    rme32->iobase + RME32_IO_DATA_BUFFER + pos,
 			    count))
 		return -EFAULT;
@@ -1205,8 +1206,7 @@ static const struct snd_pcm_ops snd_rme32_playback_spdif_ops = {
 	.prepare =	snd_rme32_playback_prepare,
 	.trigger =	snd_rme32_pcm_trigger,
 	.pointer =	snd_rme32_playback_pointer,
-	.copy =		snd_rme32_playback_copy,
-	.silence =	snd_rme32_playback_silence,
+	.copy_silence =	snd_rme32_playback_copy,
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
@@ -1219,7 +1219,7 @@ static const struct snd_pcm_ops snd_rme32_capture_spdif_ops = {
 	.prepare =	snd_rme32_capture_prepare,
 	.trigger =	snd_rme32_pcm_trigger,
 	.pointer =	snd_rme32_capture_pointer,
-	.copy =		snd_rme32_capture_copy,
+	.copy_silence =	snd_rme32_capture_copy,
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
@@ -1231,8 +1231,7 @@ static const struct snd_pcm_ops snd_rme32_playback_adat_ops = {
 	.prepare =	snd_rme32_playback_prepare,
 	.trigger =	snd_rme32_pcm_trigger,
 	.pointer =	snd_rme32_playback_pointer,
-	.copy =		snd_rme32_playback_copy,
-	.silence =	snd_rme32_playback_silence,
+	.copy_silence =	snd_rme32_playback_copy,
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
@@ -1244,7 +1243,7 @@ static const struct snd_pcm_ops snd_rme32_capture_adat_ops = {
 	.prepare =	snd_rme32_capture_prepare,
 	.trigger =	snd_rme32_pcm_trigger,
 	.pointer =	snd_rme32_capture_pointer,
-	.copy =		snd_rme32_capture_copy,
+	.copy_silence =	snd_rme32_capture_copy,
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 08/16] ALSA: rme96: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (6 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 07/16] ALSA: rme32: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 09/16] ALSA: rme9652: " Takashi Iwai
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
The conversion is straightforward with standard helper functions.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/rme96.c | 52 ++++++++++++++++++++++++++--------------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 05b9da30990d..2161f6aad532 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -326,31 +326,25 @@ snd_rme96_capture_ptr(struct rme96 *rme96)
 }
 
 static int
-snd_rme96_playback_silence(struct snd_pcm_substream *substream,
-			   int channel, /* not used (interleaved data) */
-			   snd_pcm_uframes_t pos,
-			   snd_pcm_uframes_t count)
-{
-	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
-	count <<= rme96->playback_frlog;
-	pos <<= rme96->playback_frlog;
-	memset_io(rme96->iobase + RME96_IO_PLAY_BUFFER + pos,
-		  0, count);
-	return 0;
-}
-
-static int
 snd_rme96_playback_copy(struct snd_pcm_substream *substream,
 			int channel, /* not used (interleaved data) */
 			snd_pcm_uframes_t pos,
 			void __user *src,
-			snd_pcm_uframes_t count)
+			snd_pcm_uframes_t count,
+			bool in_kernel)
 {
 	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	count <<= rme96->playback_frlog;
 	pos <<= rme96->playback_frlog;
-	return copy_from_user_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, src,
-				   count);
+	if (!src)
+		memset_io(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, 0, count);
+	else if (in_kernel)
+		memcpy_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos,
+			    (void *)src, count);
+	else if (copy_from_user_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos,
+				     src, count))
+		return -EFAULT;
+	return 0;
 }
 
 static int
@@ -358,13 +352,21 @@ snd_rme96_capture_copy(struct snd_pcm_substream *substream,
 		       int channel, /* not used (interleaved data) */
 		       snd_pcm_uframes_t pos,
 		       void __user *dst,
-		       snd_pcm_uframes_t count)
+		       snd_pcm_uframes_t count,
+		       bool in_kernel)
 {
 	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	count <<= rme96->capture_frlog;
 	pos <<= rme96->capture_frlog;
-	return copy_to_user_fromio(dst, rme96->iobase + RME96_IO_REC_BUFFER + pos,
-				   count);
+	if (in_kernel)
+		memcpy_fromio((void *)dst,
+			      rme96->iobase + RME96_IO_REC_BUFFER + pos,
+			      count);
+	else if (copy_to_user_fromio(dst,
+				     rme96->iobase + RME96_IO_REC_BUFFER + pos,
+				     count))
+		return -EFAULT;
+	return 0;
 }
 
 /*
@@ -1513,8 +1515,7 @@ static const struct snd_pcm_ops snd_rme96_playback_spdif_ops = {
 	.prepare =	snd_rme96_playback_prepare,
 	.trigger =	snd_rme96_playback_trigger,
 	.pointer =	snd_rme96_playback_pointer,
-	.copy =		snd_rme96_playback_copy,
-	.silence =	snd_rme96_playback_silence,
+	.copy_silence =	snd_rme96_playback_copy,
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
@@ -1526,7 +1527,7 @@ static const struct snd_pcm_ops snd_rme96_capture_spdif_ops = {
 	.prepare =	snd_rme96_capture_prepare,
 	.trigger =	snd_rme96_capture_trigger,
 	.pointer =	snd_rme96_capture_pointer,
-	.copy =		snd_rme96_capture_copy,
+	.copy_silence =	snd_rme96_capture_copy,
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
@@ -1538,8 +1539,7 @@ static const struct snd_pcm_ops snd_rme96_playback_adat_ops = {
 	.prepare =	snd_rme96_playback_prepare,
 	.trigger =	snd_rme96_playback_trigger,
 	.pointer =	snd_rme96_playback_pointer,
-	.copy =		snd_rme96_playback_copy,
-	.silence =	snd_rme96_playback_silence,
+	.copy_silence =	snd_rme96_playback_copy,
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
@@ -1551,7 +1551,7 @@ static const struct snd_pcm_ops snd_rme96_capture_adat_ops = {
 	.prepare =	snd_rme96_capture_prepare,
 	.trigger =	snd_rme96_capture_trigger,
 	.pointer =	snd_rme96_capture_pointer,
-	.copy =		snd_rme96_capture_copy,
+	.copy_silence =	snd_rme96_capture_copy,
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 09/16] ALSA: rme9652: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (7 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 08/16] ALSA: rme96: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 10/16] ALSA: hdsp: " Takashi Iwai
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
The conversion is straightforward with standard helper functions.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/rme9652/rme9652.c | 46 ++++++++++++++++++++-------------------------
 1 file changed, 20 insertions(+), 26 deletions(-)

diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 55172c689991..ce9faa32c7ed 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -1883,8 +1883,10 @@ static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
 	}
 }
 
-static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, int channel,
-				     snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
+static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream,
+				     int channel, snd_pcm_uframes_t pos,
+				     void __user *src, snd_pcm_uframes_t count,
+				     bool in_kernel)
 {
 	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 	char *channel_buf;
@@ -1897,13 +1899,19 @@ static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, int ch
 						       channel);
 	if (snd_BUG_ON(!channel_buf))
 		return -EIO;
-	if (copy_from_user(channel_buf + pos * 4, src, count * 4))
+	if (!src)
+		memset(channel_buf + pos * 4, 0, count * 4);
+	else if (in_kernel)
+		memcpy(channel_buf + pos * 4, (void *)src, count * 4);
+	else if (copy_from_user(channel_buf + pos * 4, src, count * 4))
 		return -EFAULT;
-	return count;
+	return 0;
 }
 
-static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, int channel,
-				    snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
+static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream,
+				    int channel, snd_pcm_uframes_t pos,
+				    void __user *dst, snd_pcm_uframes_t count,
+				    bool in_kernel)
 {
 	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 	char *channel_buf;
@@ -1916,24 +1924,11 @@ static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, int cha
 						       channel);
 	if (snd_BUG_ON(!channel_buf))
 		return -EIO;
-	if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
+	if (in_kernel)
+		memcpy((void *)dst, channel_buf + pos * 4, count * 4);
+	else if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
 		return -EFAULT;
-	return count;
-}
-
-static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream, int channel,
-				  snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
-{
-	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
-	char *channel_buf;
-
-	channel_buf = rme9652_channel_buffer_location (rme9652,
-						       substream->pstr->stream,
-						       channel);
-	if (snd_BUG_ON(!channel_buf))
-		return -EIO;
-	memset(channel_buf + pos * 4, 0, count * 4);
-	return count;
+	return 0;
 }
 
 static int snd_rme9652_reset(struct snd_pcm_substream *substream)
@@ -2376,8 +2371,7 @@ static const struct snd_pcm_ops snd_rme9652_playback_ops = {
 	.prepare =	snd_rme9652_prepare,
 	.trigger =	snd_rme9652_trigger,
 	.pointer =	snd_rme9652_hw_pointer,
-	.copy =		snd_rme9652_playback_copy,
-	.silence =	snd_rme9652_hw_silence,
+	.copy_silence =	snd_rme9652_playback_copy,
 };
 
 static const struct snd_pcm_ops snd_rme9652_capture_ops = {
@@ -2388,7 +2382,7 @@ static const struct snd_pcm_ops snd_rme9652_capture_ops = {
 	.prepare =	snd_rme9652_prepare,
 	.trigger =	snd_rme9652_trigger,
 	.pointer =	snd_rme9652_hw_pointer,
-	.copy =		snd_rme9652_capture_copy,
+	.copy_silence =	snd_rme9652_capture_copy,
 };
 
 static int snd_rme9652_create_pcm(struct snd_card *card,
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 10/16] ALSA: hdsp: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (8 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 09/16] ALSA: rme9652: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 11/16] ALSA: gus: " Takashi Iwai
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
The conversion is straightforward with standard helper functions.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/rme9652/hdsp.c | 44 ++++++++++++++++++++------------------------
 1 file changed, 20 insertions(+), 24 deletions(-)

diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index fc0face6cdc6..5325e91fc3a8 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -3913,8 +3913,10 @@ static char *hdsp_channel_buffer_location(struct hdsp *hdsp,
 		return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
 }
 
-static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream, int channel,
-				  snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
+static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream,
+				  int channel, snd_pcm_uframes_t pos,
+				  void __user *src, snd_pcm_uframes_t count,
+				  bool in_kernel)
 {
 	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 	char *channel_buf;
@@ -3925,13 +3927,19 @@ static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream, int chann
 	channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
 	if (snd_BUG_ON(!channel_buf))
 		return -EIO;
-	if (copy_from_user(channel_buf + pos * 4, src, count * 4))
+	if (!src)
+		memset(channel_buf + pos * 4, 0, count * 4);
+	else if (in_kernel)
+		memcpy(channel_buf + pos * 4, (void *)src, count * 4);
+	else if (copy_from_user(channel_buf + pos * 4, src, count * 4))
 		return -EFAULT;
-	return count;
+	return 0;
 }
 
-static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream, int channel,
-				 snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
+static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream,
+				 int channel, snd_pcm_uframes_t pos,
+				 void __user *dst, snd_pcm_uframes_t count,
+				 bool in_kernel)
 {
 	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 	char *channel_buf;
@@ -3942,22 +3950,11 @@ static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream, int channe
 	channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
 	if (snd_BUG_ON(!channel_buf))
 		return -EIO;
-	if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
+	if (in_kernel)
+		memcpy((void *)dst, channel_buf + pos * 4, count * 4);
+	else if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
 		return -EFAULT;
-	return count;
-}
-
-static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream, int channel,
-				  snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
-{
-	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
-	char *channel_buf;
-
-	channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
-	if (snd_BUG_ON(!channel_buf))
-		return -EIO;
-	memset(channel_buf + pos * 4, 0, count * 4);
-	return count;
+	return 0;
 }
 
 static int snd_hdsp_reset(struct snd_pcm_substream *substream)
@@ -4869,8 +4866,7 @@ static const struct snd_pcm_ops snd_hdsp_playback_ops = {
 	.prepare =	snd_hdsp_prepare,
 	.trigger =	snd_hdsp_trigger,
 	.pointer =	snd_hdsp_hw_pointer,
-	.copy =		snd_hdsp_playback_copy,
-	.silence =	snd_hdsp_hw_silence,
+	.copy_silence =	snd_hdsp_playback_copy,
 };
 
 static const struct snd_pcm_ops snd_hdsp_capture_ops = {
@@ -4881,7 +4877,7 @@ static const struct snd_pcm_ops snd_hdsp_capture_ops = {
 	.prepare =	snd_hdsp_prepare,
 	.trigger =	snd_hdsp_trigger,
 	.pointer =	snd_hdsp_hw_pointer,
-	.copy =		snd_hdsp_capture_copy,
+	.copy_silence =	snd_hdsp_capture_copy,
 };
 
 static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp)
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 11/16] ALSA: gus: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (9 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 10/16] ALSA: hdsp: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 12/16] ALSA: sb: " Takashi Iwai
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
The conversion is straightforward with standard helper functions.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/isa/gus/gus_pcm.c | 43 +++++++++----------------------------------
 1 file changed, 9 insertions(+), 34 deletions(-)

diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index 33c1891f469a..c541370d3d76 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -359,7 +359,8 @@ static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream,
 				     int voice,
 				     snd_pcm_uframes_t pos,
 				     void __user *src,
-				     snd_pcm_uframes_t count)
+				     snd_pcm_uframes_t count,
+				     bool in_kernel)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct gus_pcm_private *pcmp = runtime->private_data;
@@ -371,7 +372,12 @@ static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream,
 		return -EIO;
 	if (snd_BUG_ON(bpos + len > pcmp->dma_size))
 		return -EIO;
-	if (copy_from_user(runtime->dma_area + bpos, src, len))
+	if (!src)
+		snd_pcm_format_set_silence(runtime->format,
+					   runtime->dma_area + bpos, count);
+	else if (in_kernel)
+		memcpy(runtime->dma_area + bpos, (void *)src, len);
+	else if (copy_from_user(runtime->dma_area + bpos, src, len))
 		return -EFAULT;
 	if (snd_gf1_pcm_use_dma && len > 32) {
 		return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len);
@@ -387,36 +393,6 @@ static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream,
-					int voice,
-					snd_pcm_uframes_t pos,
-					snd_pcm_uframes_t count)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct gus_pcm_private *pcmp = runtime->private_data;
-	unsigned int bpos, len;
-	
-	bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2));
-	len = samples_to_bytes(runtime, count);
-	if (snd_BUG_ON(bpos > pcmp->dma_size))
-		return -EIO;
-	if (snd_BUG_ON(bpos + len > pcmp->dma_size))
-		return -EIO;
-	snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos, count);
-	if (snd_gf1_pcm_use_dma && len > 32) {
-		return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len);
-	} else {
-		struct snd_gus_card *gus = pcmp->gus;
-		int err, w16, invert;
-
-		w16 = (snd_pcm_format_width(runtime->format) == 16);
-		invert = snd_pcm_format_unsigned(runtime->format);
-		if ((err = snd_gf1_pcm_poke_block(gus, runtime->dma_area + bpos, pcmp->memory + bpos, len, w16, invert)) < 0)
-			return err;
-	}
-	return 0;
-}
-
 static int snd_gf1_pcm_playback_hw_params(struct snd_pcm_substream *substream,
 					  struct snd_pcm_hw_params *hw_params)
 {
@@ -836,8 +812,7 @@ static struct snd_pcm_ops snd_gf1_pcm_playback_ops = {
 	.prepare =	snd_gf1_pcm_playback_prepare,
 	.trigger =	snd_gf1_pcm_playback_trigger,
 	.pointer =	snd_gf1_pcm_playback_pointer,
-	.copy =		snd_gf1_pcm_playback_copy,
-	.silence =	snd_gf1_pcm_playback_silence,
+	.copy_silence =	snd_gf1_pcm_playback_copy,
 };
 
 static struct snd_pcm_ops snd_gf1_pcm_capture_ops = {
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 12/16] ALSA: sb: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (10 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 11/16] ALSA: gus: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 13/16] ALSA: sh: " Takashi Iwai
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
We could reduce the redundant silence code by that.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/isa/sb/emu8000_pcm.c | 99 ++++++++++++++--------------------------------
 1 file changed, 30 insertions(+), 69 deletions(-)

diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index 32f234f494e5..fd42ae2f73b8 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -422,16 +422,28 @@ do { \
 		return -EAGAIN;\
 } while (0)
 
+static inline int get_val(unsigned short *sval, unsigned short __user *buf,
+			  bool in_kernel)
+{
+	if (!buf)
+		*sval = 0;
+	else if (in_kernel)
+		*sval = *(unsigned short *)buf;
+	else if (get_user(*sval, buf))
+		return -EFAULT;
+	return 0;
+}
 
 #ifdef USE_NONINTERLEAVE
 /* copy one channel block */
-static int emu8k_transfer_block(struct snd_emu8000 *emu, int offset, unsigned short *buf, int count)
+static int emu8k_transfer_block(struct snd_emu8000 *emu, int offset,
+				unsigned short *buf, int count, bool in_kernel)
 {
 	EMU8000_SMALW_WRITE(emu, offset);
 	while (count > 0) {
 		unsigned short sval;
 		CHECK_SCHEDULER();
-		if (get_user(sval, buf))
+		if (get_val(&sval, buf, in_kernel))
 			return -EFAULT;
 		EMU8000_SMLD_WRITE(emu, sval);
 		buf++;
@@ -455,48 +467,18 @@ static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
 		int i, err;
 		count /= rec->voices;
 		for (i = 0; i < rec->voices; i++) {
-			err = emu8k_transfer_block(emu, pos + rec->loop_start[i], buf, count);
+			err = emu8k_transfer_block(emu,
+						   pos + rec->loop_start[i],
+						   buf, count, in_kernel);
 			if (err < 0)
 				return err;
-			buf += count;
+			if (buf)
+				buf += count;
 		}
 		return 0;
 	} else {
-		return emu8k_transfer_block(emu, pos + rec->loop_start[voice], src, count);
-	}
-}
-
-/* make a channel block silence */
-static int emu8k_silence_block(struct snd_emu8000 *emu, int offset, int count)
-{
-	EMU8000_SMALW_WRITE(emu, offset);
-	while (count > 0) {
-		CHECK_SCHEDULER();
-		EMU8000_SMLD_WRITE(emu, 0);
-		count--;
-	}
-	return 0;
-}
-
-static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
-			     int voice,
-			     snd_pcm_uframes_t pos,
-			     snd_pcm_uframes_t count)
-{
-	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
-	struct snd_emu8000 *emu = rec->emu;
-
-	snd_emu8000_write_wait(emu, 1);
-	if (voice == -1 && rec->voices == 1)
-		voice = 0;
-	if (voice == -1) {
-		int err;
-		err = emu8k_silence_block(emu, pos + rec->loop_start[0], count / 2);
-		if (err < 0)
-			return err;
-		return emu8k_silence_block(emu, pos + rec->loop_start[1], count / 2);
-	} else {
-		return emu8k_silence_block(emu, pos + rec->loop_start[voice], count);
+		return emu8k_transfer_block(emu, pos + rec->loop_start[voice],
+					    src, count, in_kernel);
 	}
 }
 
@@ -510,7 +492,8 @@ static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
 			  int voice,
 			  snd_pcm_uframes_t pos,
 			  void __user *src,
-			  snd_pcm_uframes_t count)
+			  snd_pcm_uframes_t count,
+			  bool in_kernel)
 {
 	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
 	struct snd_emu8000 *emu = rec->emu;
@@ -524,39 +507,18 @@ static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
 	while (count-- > 0) {
 		unsigned short sval;
 		CHECK_SCHEDULER();
-		if (get_user(sval, buf))
+		if (get_val(&sval, buf, in_kernel))
 			return -EFAULT;
 		EMU8000_SMLD_WRITE(emu, sval);
-		buf++;
+		if (buf)
+			buf++;
 		if (rec->voices > 1) {
 			CHECK_SCHEDULER();
-			if (get_user(sval, buf))
+			if (get_val(&sval, buf, in_kernel))
 				return -EFAULT;
 			EMU8000_SMRD_WRITE(emu, sval);
-			buf++;
-		}
-	}
-	return 0;
-}
-
-static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
-			     int voice,
-			     snd_pcm_uframes_t pos,
-			     snd_pcm_uframes_t count)
-{
-	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
-	struct snd_emu8000 *emu = rec->emu;
-
-	snd_emu8000_write_wait(emu, 1);
-	EMU8000_SMALW_WRITE(emu, rec->loop_start[0] + pos);
-	if (rec->voices > 1)
-		EMU8000_SMARW_WRITE(emu, rec->loop_start[1] + pos);
-	while (count-- > 0) {
-		CHECK_SCHEDULER();
-		EMU8000_SMLD_WRITE(emu, 0);
-		if (rec->voices > 1) {
-			CHECK_SCHEDULER();
-			EMU8000_SMRD_WRITE(emu, 0);
+			if (buf)
+				buf++;
 		}
 	}
 	return 0;
@@ -674,8 +636,7 @@ static struct snd_pcm_ops emu8k_pcm_ops = {
 	.prepare =	emu8k_pcm_prepare,
 	.trigger =	emu8k_pcm_trigger,
 	.pointer =	emu8k_pcm_pointer,
-	.copy =		emu8k_pcm_copy,
-	.silence =	emu8k_pcm_silence,
+	.copy_silence =	emu8k_pcm_copy,
 };
 
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 13/16] ALSA: sh: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (11 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 12/16] ALSA: sb: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-21 20:09 ` [PATCH 14/16] ASoC: blackfin: " Takashi Iwai
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
A straightforward conversion with standard helper functions.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/sh/sh_dac_audio.c | 40 +++++++++-------------------------------
 1 file changed, 9 insertions(+), 31 deletions(-)

diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index 461b310c7872..a4014a4548d0 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -185,7 +185,8 @@ static int snd_sh_dac_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 }
 
 static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, int channel,
-	snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
+			       snd_pcm_uframes_t pos, void __user *src,
+			       snd_pcm_uframes_t count, bool in_kernel)
 {
 	/* channel is not used (interleaved data) */
 	struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
@@ -199,34 +200,12 @@ static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, int channel,
 	if (!count)
 		return 0;
 
-	memcpy_toio(chip->data_buffer + b_pos, src, b_count);
-	chip->buffer_end = chip->data_buffer + b_pos + b_count;
-
-	if (chip->empty) {
-		chip->empty = 0;
-		dac_audio_start_timer(chip);
-	}
-
-	return 0;
-}
-
-static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream,
-				  int channel, snd_pcm_uframes_t pos,
-				  snd_pcm_uframes_t count)
-{
-	/* channel is not used (interleaved data) */
-	struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	ssize_t b_count = frames_to_bytes(runtime , count);
-	ssize_t b_pos = frames_to_bytes(runtime , pos);
-
-	if (count < 0)
-		return -EINVAL;
-
-	if (!count)
-		return 0;
-
-	memset_io(chip->data_buffer + b_pos, 0, b_count);
+	if (!src)
+		memset_io(chip->data_buffer + b_pos, 0, b_count);
+	else if (in_kernel)
+		memcpy_toio(chip->data_buffer + b_pos, (void *)src, b_count);
+	else if (copy_from_user_toio(chip->data_buffer + b_pos, src, b_count))
+		return -EFAULT;
 	chip->buffer_end = chip->data_buffer + b_pos + b_count;
 
 	if (chip->empty) {
@@ -256,8 +235,7 @@ static struct snd_pcm_ops snd_sh_dac_pcm_ops = {
 	.prepare	= snd_sh_dac_pcm_prepare,
 	.trigger	= snd_sh_dac_pcm_trigger,
 	.pointer	= snd_sh_dac_pcm_pointer,
-	.copy		= snd_sh_dac_pcm_copy,
-	.silence	= snd_sh_dac_pcm_silence,
+	.copy_silence	= snd_sh_dac_pcm_copy,
 	.mmap		= snd_pcm_lib_mmap_iomem,
 };
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 14/16] ASoC: blackfin: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (12 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 13/16] ALSA: sh: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-22  9:27     ` Mark Brown
  2017-05-21 20:09 ` [PATCH 15/16] [media] solo6x10: " Takashi Iwai
  2017-05-21 20:09 ` [PATCH 16/16] ALSA: pcm: Drop the old copy and silence ops Takashi Iwai
  15 siblings, 1 reply; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
The silence is performed only when CONFIG_SND_BF5XX_MMAP_SUPPORT is
set (since copy_silence ops is set only with this config), so in
bf5xx-ac97.c we have a bit tricky macro for a slight optimization.

Note that we don't need to take in_kernel into account on this
architecture, so the conversion is easy otherwise.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/soc/blackfin/bf5xx-ac97-pcm.c |  6 ++---
 sound/soc/blackfin/bf5xx-ac97.c     | 18 ++++++++++-----
 sound/soc/blackfin/bf5xx-i2s-pcm.c  | 46 ++++++++++++-------------------------
 3 files changed, 30 insertions(+), 40 deletions(-)

diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 02ad2606fa19..2fdffa7d376c 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -280,8 +280,8 @@ static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
 }
 #else
 static	int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
-		    snd_pcm_uframes_t pos,
-		    void __user *buf, snd_pcm_uframes_t count)
+			   snd_pcm_uframes_t pos, void __user *buf,
+			   snd_pcm_uframes_t count, bool in_kernel)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
@@ -309,7 +309,7 @@ static struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
 #if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
 	.mmap		= bf5xx_pcm_mmap,
 #else
-	.copy		= bf5xx_pcm_copy,
+	.copy_silence	= bf5xx_pcm_copy,
 #endif
 };
 
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index a040cfe29fc0..d1f11d9ecb07 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -43,35 +43,41 @@
 
 static struct sport_device *ac97_sport_handle;
 
+#ifdef CONFIG_SND_BF5XX_MMAP_SUPPORT
+#define GET_VAL(src)	(*src++)		/* copy only */
+#else
+#define GET_VAL(src)	(src ? *src++ : 0)	/* copy/silence */
+#endif
+
 void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
 		size_t count, unsigned int chan_mask)
 {
 	while (count--) {
 		dst->ac97_tag = TAG_VALID;
 		if (chan_mask & SP_FL) {
-			dst->ac97_pcm_r = *src++;
+			dst->ac97_pcm_r = GET_VAL(src);
 			dst->ac97_tag |= TAG_PCM_RIGHT;
 		}
 		if (chan_mask & SP_FR) {
-			dst->ac97_pcm_l = *src++;
+			dst->ac97_pcm_l = GET_VAL(src);
 			dst->ac97_tag |= TAG_PCM_LEFT;
 
 		}
 #if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
 		if (chan_mask & SP_SR) {
-			dst->ac97_sl = *src++;
+			dst->ac97_sl = GET_VAL(src);
 			dst->ac97_tag |= TAG_PCM_SL;
 		}
 		if (chan_mask & SP_SL) {
-			dst->ac97_sr = *src++;
+			dst->ac97_sr = GET_VAL(src);
 			dst->ac97_tag |= TAG_PCM_SR;
 		}
 		if (chan_mask & SP_LFE) {
-			dst->ac97_lfe = *src++;
+			dst->ac97_lfe = GET_VAL(src);
 			dst->ac97_tag |= TAG_PCM_LFE;
 		}
 		if (chan_mask & SP_FC) {
-			dst->ac97_center = *src++;
+			dst->ac97_center = GET_VAL(src);
 			dst->ac97_tag |= TAG_PCM_CENTER;
 		}
 #endif
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 6cba211da32e..5686c29fb058 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -226,7 +226,8 @@ static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
 }
 
 static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
-	snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count)
+			  snd_pcm_uframes_t pos, void *buf,
+			  snd_pcm_uframes_t count, bool in_kernel)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime *runtime = substream->runtime;
@@ -245,8 +246,14 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
 
 			while (count--) {
 				for (i = 0; i < runtime->channels; i++) {
-					memcpy(dst + dma_data->map[i] *
-						sample_size, src, sample_size);
+					if (!buf)
+						memset(dst + dma_data->map[i] *
+						       sample_size, 0,
+						       sample_size);
+					else
+						memcpy(dst + dma_data->map[i] *
+						       sample_size, src,
+						       sample_size);
 					src += sample_size;
 				}
 				dst += 8 * sample_size;
@@ -276,34 +283,12 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
 			dst = buf;
 		}
 
-		memcpy(dst, src, frames_to_bytes(runtime, count));
-	}
-
-	return 0;
-}
-
-static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
-	int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	unsigned int sample_size = runtime->sample_bits / 8;
-	void *buf = runtime->dma_area;
-	struct bf5xx_i2s_pcm_data *dma_data;
-	unsigned int offset, samples;
-
-	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-	if (dma_data->tdm_mode) {
-		offset = pos * 8 * sample_size;
-		samples = count * 8;
-	} else {
-		offset = frames_to_bytes(runtime, pos);
-		samples = count * runtime->channels;
+		if (!buf)
+			memset(dst, 0, frames_to_bytes(runtime, count));
+		else
+			memcpy(dst, src, frames_to_bytes(runtime, count));
 	}
 
-	snd_pcm_format_set_silence(runtime->format, buf + offset, samples);
-
 	return 0;
 }
 
@@ -316,8 +301,7 @@ static struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
 	.trigger	= bf5xx_pcm_trigger,
 	.pointer	= bf5xx_pcm_pointer,
 	.mmap		= bf5xx_pcm_mmap,
-	.copy		= bf5xx_pcm_copy,
-	.silence	= bf5xx_pcm_silence,
+	.copy_silence	= bf5xx_pcm_copy,
 };
 
 static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 15/16] [media] solo6x10: Convert to copy_silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (13 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 14/16] ASoC: blackfin: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  2017-05-22  7:21   ` Hans Verkuil
  2017-05-21 20:09 ` [PATCH 16/16] ALSA: pcm: Drop the old copy and silence ops Takashi Iwai
  15 siblings, 1 reply; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Replace the copy and the silence ops with the new merged ops.
It's a capture stream, thus no silence is needed.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 drivers/media/pci/solo6x10/solo6x10-g723.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/media/pci/solo6x10/solo6x10-g723.c b/drivers/media/pci/solo6x10/solo6x10-g723.c
index 36e93540bb49..e21db3efb748 100644
--- a/drivers/media/pci/solo6x10/solo6x10-g723.c
+++ b/drivers/media/pci/solo6x10/solo6x10-g723.c
@@ -225,7 +225,7 @@ static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss)
 
 static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel,
 			     snd_pcm_uframes_t pos, void __user *dst,
-			     snd_pcm_uframes_t count)
+			     snd_pcm_uframes_t count, bool in_kernel)
 {
 	struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss);
 	struct solo_dev *solo_dev = solo_pcm->solo_dev;
@@ -242,10 +242,11 @@ static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel,
 		if (err)
 			return err;
 
-		err = copy_to_user(dst + (i * G723_PERIOD_BYTES),
-				   solo_pcm->g723_buf, G723_PERIOD_BYTES);
-
-		if (err)
+		if (in_kernel)
+			memcpy((void *)dst + (i * G723_PERIOD_BYTES),
+			       solo_pcm->g723_buf, G723_PERIOD_BYTES);
+		else if (copy_to_user(dst + (i * G723_PERIOD_BYTES),
+				      solo_pcm->g723_buf, G723_PERIOD_BYTES))
 			return -EFAULT;
 	}
 
@@ -261,7 +262,7 @@ static const struct snd_pcm_ops snd_solo_pcm_ops = {
 	.prepare = snd_solo_pcm_prepare,
 	.trigger = snd_solo_pcm_trigger,
 	.pointer = snd_solo_pcm_pointer,
-	.copy = snd_solo_pcm_copy,
+	.copy_silence = snd_solo_pcm_copy,
 };
 
 static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol,
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 16/16] ALSA: pcm: Drop the old copy and silence ops
  2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
                   ` (14 preceding siblings ...)
  2017-05-21 20:09 ` [PATCH 15/16] [media] solo6x10: " Takashi Iwai
@ 2017-05-21 20:09 ` Takashi Iwai
  15 siblings, 0 replies; 21+ messages in thread
From: Takashi Iwai @ 2017-05-21 20:09 UTC (permalink / raw)
  To: alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

Now that all users of old copy and silence ops have been converted to
the new copy_silence ops, the old stuff can be retired and go away.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/sound/pcm.h  |  5 -----
 sound/core/pcm_lib.c | 38 +-------------------------------------
 sound/soc/soc-pcm.c  |  2 --
 3 files changed, 1 insertion(+), 44 deletions(-)

diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index b9dd813dd885..4243c02c3f11 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -78,11 +78,6 @@ struct snd_pcm_ops {
 			struct timespec *system_ts, struct timespec *audio_ts,
 			struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
 			struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
-	int (*copy)(struct snd_pcm_substream *substream, int channel,
-		    snd_pcm_uframes_t pos,
-		    void __user *buf, snd_pcm_uframes_t count);
-	int (*silence)(struct snd_pcm_substream *substream, int channel, 
-		       snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
 	int (*copy_silence)(struct snd_pcm_substream *substream, int channel,
 			    snd_pcm_uframes_t pos, void __user *buf,
 			    snd_pcm_uframes_t count, bool in_kernel);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index b720cbda017f..1c9d43fefacc 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -115,9 +115,6 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
 				err = substream->ops->copy_silence(substream,
 					-1, ofs, NULL, transfer, false);
 				snd_BUG_ON(err < 0);
-			} else if (substream->ops->silence) {
-				err = substream->ops->silence(substream, -1, ofs, transfer);
-				snd_BUG_ON(err < 0);
 			} else {
 				hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs);
 				snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels);
@@ -131,11 +128,6 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
 						c, ofs, NULL, transfer, false);
 					snd_BUG_ON(err < 0);
 				}
-			} else if (substream->ops->silence) {
-				for (c = 0; c < channels; ++c) {
-					err = substream->ops->silence(substream, c, ofs, transfer);
-					snd_BUG_ON(err < 0);
-				}
 			} else {
 				size_t dma_csize = runtime->dma_bytes / channels;
 				for (c = 0; c < channels; ++c) {
@@ -2010,9 +2002,6 @@ static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
 						   frames, false);
 		if (err < 0)
 			return err;
-	} else if (substream->ops->copy) {
-		if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
-			return err;
 	} else {
 		char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
 		if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames)))
@@ -2134,8 +2123,7 @@ static int pcm_sanity_check(struct snd_pcm_substream *substream)
 	if (PCM_RUNTIME_CHECK(substream))
 		return -ENXIO;
 	runtime = substream->runtime;
-	if (snd_BUG_ON(!substream->ops->copy_silence && !substream->ops->copy
-		       && !runtime->dma_area))
+	if (snd_BUG_ON(!substream->ops->copy_silence && !runtime->dma_area))
 		return -EINVAL;
 	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
 		return -EBADFD;
@@ -2186,19 +2174,6 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
 			if (err < 0)
 				return err;
 		}
-	} else if (substream->ops->copy) {
-		if (snd_BUG_ON(!substream->ops->silence))
-			return -EINVAL;
-		for (c = 0; c < channels; ++c, ++bufs) {
-			if (*bufs == NULL) {
-				if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0)
-					return err;
-			} else {
-				buf = *bufs + samples_to_bytes(runtime, off);
-				if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0)
-					return err;
-			}
-		}
 	} else {
 		/* default transfer behaviour */
 		size_t dma_csize = runtime->dma_bytes / channels;
@@ -2251,9 +2226,6 @@ static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
 						   frames, false);
 		if (err < 0)
 			return err;
-	} else if (substream->ops->copy) {
-		if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
-			return err;
 	} else {
 		char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
 		if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames)))
@@ -2413,14 +2385,6 @@ static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
 			if (err < 0)
 				return err;
 		}
-	} else if (substream->ops->copy) {
-		for (c = 0; c < channels; ++c, ++bufs) {
-			if (*bufs == NULL)
-				continue;
-			buf = *bufs + samples_to_bytes(runtime, off);
-			if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0)
-				return err;
-		}
 	} else {
 		snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels;
 		for (c = 0; c < channels; ++c, ++bufs) {
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 3cfb9aa1203b..5d58d8434971 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -2744,8 +2744,6 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
 	if (platform->driver->ops) {
 		rtd->ops.ack		= platform->driver->ops->ack;
 		rtd->ops.copy_silence	= platform->driver->ops->copy_silence;
-		rtd->ops.copy		= platform->driver->ops->copy;
-		rtd->ops.silence	= platform->driver->ops->silence;
 		rtd->ops.page		= platform->driver->ops->page;
 		rtd->ops.mmap		= platform->driver->ops->mmap;
 	}
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 15/16] [media] solo6x10: Convert to copy_silence ops
  2017-05-21 20:09 ` [PATCH 15/16] [media] solo6x10: " Takashi Iwai
@ 2017-05-22  7:21   ` Hans Verkuil
  0 siblings, 0 replies; 21+ messages in thread
From: Hans Verkuil @ 2017-05-22  7:21 UTC (permalink / raw)
  To: Takashi Iwai, alsa-devel
  Cc: Takashi Sakamoto, Mark Brown, Bluecherry Maintainers, linux-media

On 05/21/2017 10:09 PM, Takashi Iwai wrote:
> Replace the copy and the silence ops with the new merged ops.
> It's a capture stream, thus no silence is needed.
> 
> Signed-off-by: Takashi Iwai <tiwai@suse.de>

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

Regards,

	Hans

> ---
>  drivers/media/pci/solo6x10/solo6x10-g723.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/pci/solo6x10/solo6x10-g723.c b/drivers/media/pci/solo6x10/solo6x10-g723.c
> index 36e93540bb49..e21db3efb748 100644
> --- a/drivers/media/pci/solo6x10/solo6x10-g723.c
> +++ b/drivers/media/pci/solo6x10/solo6x10-g723.c
> @@ -225,7 +225,7 @@ static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss)
>  
>  static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel,
>  			     snd_pcm_uframes_t pos, void __user *dst,
> -			     snd_pcm_uframes_t count)
> +			     snd_pcm_uframes_t count, bool in_kernel)
>  {
>  	struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss);
>  	struct solo_dev *solo_dev = solo_pcm->solo_dev;
> @@ -242,10 +242,11 @@ static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel,
>  		if (err)
>  			return err;
>  
> -		err = copy_to_user(dst + (i * G723_PERIOD_BYTES),
> -				   solo_pcm->g723_buf, G723_PERIOD_BYTES);
> -
> -		if (err)
> +		if (in_kernel)
> +			memcpy((void *)dst + (i * G723_PERIOD_BYTES),
> +			       solo_pcm->g723_buf, G723_PERIOD_BYTES);
> +		else if (copy_to_user(dst + (i * G723_PERIOD_BYTES),
> +				      solo_pcm->g723_buf, G723_PERIOD_BYTES))
>  			return -EFAULT;
>  	}
>  
> @@ -261,7 +262,7 @@ static const struct snd_pcm_ops snd_solo_pcm_ops = {
>  	.prepare = snd_solo_pcm_prepare,
>  	.trigger = snd_solo_pcm_trigger,
>  	.pointer = snd_solo_pcm_pointer,
> -	.copy = snd_solo_pcm_copy,
> +	.copy_silence = snd_solo_pcm_copy,
>  };
>  
>  static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol,
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 14/16] ASoC: blackfin: Convert to copy_silence ops
  2017-05-21 20:09 ` [PATCH 14/16] ASoC: blackfin: " Takashi Iwai
@ 2017-05-22  9:27     ` Mark Brown
  0 siblings, 0 replies; 21+ messages in thread
From: Mark Brown @ 2017-05-22  9:27 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: alsa-devel, Takashi Sakamoto, Bluecherry Maintainers, linux-media

[-- Attachment #1: Type: text/plain, Size: 506 bytes --]

On Sun, May 21, 2017 at 10:09:48PM +0200, Takashi Iwai wrote:
> Replace the copy and the silence ops with the new merged ops.
> The silence is performed only when CONFIG_SND_BF5XX_MMAP_SUPPORT is
> set (since copy_silence ops is set only with this config), so in
> bf5xx-ac97.c we have a bit tricky macro for a slight optimization.
> 
> Note that we don't need to take in_kernel into account on this
> architecture, so the conversion is easy otherwise.

Acked-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 14/16] ASoC: blackfin: Convert to copy_silence ops
@ 2017-05-22  9:27     ` Mark Brown
  0 siblings, 0 replies; 21+ messages in thread
From: Mark Brown @ 2017-05-22  9:27 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: alsa-devel, linux-media, Bluecherry Maintainers, Takashi Sakamoto


[-- Attachment #1.1: Type: text/plain, Size: 506 bytes --]

On Sun, May 21, 2017 at 10:09:48PM +0200, Takashi Iwai wrote:
> Replace the copy and the silence ops with the new merged ops.
> The silence is performed only when CONFIG_SND_BF5XX_MMAP_SUPPORT is
> set (since copy_silence ops is set only with this config), so in
> bf5xx-ac97.c we have a bit tricky macro for a slight optimization.
> 
> Note that we don't need to take in_kernel into account on this
> architecture, so the conversion is easy otherwise.

Acked-by: Mark Brown <broonie@kernel.org>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2017-05-22  9:28 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-21 20:09 [PATCH 00/16] ALSA: Convert to new copy_silence PCM ops Takashi Iwai
2017-05-21 20:09 ` [PATCH 01/16] ALSA: pcm: Introduce " Takashi Iwai
2017-05-21 20:09   ` Takashi Iwai
2017-05-21 20:09 ` [PATCH 02/16] ALSA: Update document about " Takashi Iwai
2017-05-21 20:09 ` [PATCH 03/16] ALSA: dummy: Convert to copy_silence ops Takashi Iwai
2017-05-21 20:09 ` [PATCH 04/16] ALSA: es1938: " Takashi Iwai
2017-05-21 20:09 ` [PATCH 05/16] ALSA: korg1212: " Takashi Iwai
2017-05-21 20:09 ` [PATCH 06/16] ALSA: nm256: " Takashi Iwai
2017-05-21 20:09 ` [PATCH 07/16] ALSA: rme32: " Takashi Iwai
2017-05-21 20:09 ` [PATCH 08/16] ALSA: rme96: " Takashi Iwai
2017-05-21 20:09 ` [PATCH 09/16] ALSA: rme9652: " Takashi Iwai
2017-05-21 20:09 ` [PATCH 10/16] ALSA: hdsp: " Takashi Iwai
2017-05-21 20:09 ` [PATCH 11/16] ALSA: gus: " Takashi Iwai
2017-05-21 20:09 ` [PATCH 12/16] ALSA: sb: " Takashi Iwai
2017-05-21 20:09 ` [PATCH 13/16] ALSA: sh: " Takashi Iwai
2017-05-21 20:09 ` [PATCH 14/16] ASoC: blackfin: " Takashi Iwai
2017-05-22  9:27   ` Mark Brown
2017-05-22  9:27     ` Mark Brown
2017-05-21 20:09 ` [PATCH 15/16] [media] solo6x10: " Takashi Iwai
2017-05-22  7:21   ` Hans Verkuil
2017-05-21 20:09 ` [PATCH 16/16] ALSA: pcm: Drop the old copy and silence ops Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.