[alsa-devel] [PATCH RFC 05/11] ALSA: core: remove duplicated codes to handle PCM frames

Takashi Sakamoto o-takashi at sakamocchi.jp
Wed May 24 02:52:49 CEST 2017


In a previous commit, common data copying operation is passed to each
of specific helper functions.

This commit removes duplicated codes in old implementations. As a result,
such old functions becomes wrappers of driver-side implementation of
'struct snd_pcm_ops.silence' and 'struct snd_pcm_ops.copy'.

Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
---
 sound/core/pcm_lib.c | 159 ++++++++++++++++++---------------------------------
 1 file changed, 57 insertions(+), 102 deletions(-)

diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 38baa91fd0f6..8dfe964e8931 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -140,17 +140,7 @@ static int writei_silence(struct snd_pcm_substream *substream,
 			  unsigned int hwoff, unsigned long data,
 			  unsigned int off, snd_pcm_uframes_t count)
 {
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	char *hwbuf;
-
-	if (substream->ops->silence)
-		return substream->ops->silence(substream, -1, hwoff, count);
-
-	hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
-	snd_pcm_format_set_silence(runtime->format, hwbuf,
-				   count * runtime->channels);
-
-	return 0;
+	return substream->ops->silence(substream, -1, hwoff, count);
 }
 
 static int writen_silence(struct snd_pcm_substream *substream,
@@ -159,25 +149,13 @@ static int writen_silence(struct snd_pcm_substream *substream,
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int channels = runtime->channels;
-	snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels;
-	char *hwbuf;
 	int c;
 	int err;
 
-	if (substream->ops->silence) {
-		for (c = 0; c < channels; ++c) {
-			err = substream->ops->silence(substream, c, hwoff,
-						      count);
-			if (err < 0)
-				return err;
-		}
-	} else {
-		for (c = 0; c < channels; ++c) {
-			hwbuf = runtime->dma_area + (c * dma_csize) +
-					samples_to_bytes(runtime, hwoff);
-			snd_pcm_format_set_silence(runtime->format, hwbuf,
-						   count);
-		}
+	for (c = 0; c < channels; ++c) {
+		err = substream->ops->silence(substream, c, hwoff, count);
+		if (err < 0)
+			return err;
 	}
 
 	return 0;
@@ -2129,20 +2107,16 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
 static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
 				      unsigned int hwoff,
 				      unsigned long data, unsigned int off,
-				      snd_pcm_uframes_t frames)
+				      snd_pcm_uframes_t count)
 {
 	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 ((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)))
-			return -EFAULT;
-	}
-	return 0;
+	char __user *buf = (char __user *) data;
+
+	if (buf == NULL && substream->ops->silence)
+		return substream->ops->silence(substream, -1, hwoff, count);
+
+	buf += frames_to_bytes(runtime, off);
+	return substream->ops->copy(substream, -1, hwoff, buf, count);
 }
  
 static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, 
@@ -2295,37 +2269,30 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
 				       snd_pcm_uframes_t frames)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	int err;
-	void __user **bufs = (void __user **)data;
+	char __user **bufs = (char __user **)data;
+	char __user *buf;
 	int channels = runtime->channels;
 	int c;
-	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 {
-				char __user *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;
-		for (c = 0; c < channels; ++c, ++bufs) {
-			char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff);
-			if (*bufs == NULL) {
-				snd_pcm_format_set_silence(runtime->format, hwbuf, frames);
-			} else {
-				char __user *buf = *bufs + samples_to_bytes(runtime, off);
-				if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames)))
-					return -EFAULT;
-			}
+	int err;
+
+	if (snd_BUG_ON(!substream->ops->silence))
+		return -EINVAL;
+
+	for (c = 0; c < channels; ++c) {
+		if (bufs == NULL || bufs[c] == NULL) {
+			err = substream->ops->silence(substream, c, hwoff,
+						      frames);
+			if (err < 0)
+				return err;
+		} else {
+			buf = bufs[c] + samples_to_bytes(runtime, off);
+			err = substream->ops->copy(substream, c, hwoff, buf,
+						   frames);
+			if (err < 0)
+				return err;
 		}
 	}
+
 	return 0;
 }
  
@@ -2363,17 +2330,13 @@ static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
 				     snd_pcm_uframes_t frames)
 {
 	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 ((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)))
-			return -EFAULT;
-	}
-	return 0;
+	char __user *buf = (char __user *)data;
+
+	if (buf == NULL)
+		return -EINVAL;
+
+	buf += frames_to_bytes(runtime, off);
+	return substream->ops->copy(substream, -1, hwoff, buf, frames);
 }
 
 static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
@@ -2518,33 +2481,25 @@ static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
 				      snd_pcm_uframes_t frames)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	int err;
-	void __user **bufs = (void __user **)data;
-	int channels = runtime->channels;
+	char __user **bufs = (char __user **)data;
+	char __user *buf;
+	unsigned int channels = runtime->channels;
 	int c;
-	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);
-			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) {
-			char *hwbuf;
-			char __user *buf;
-			if (*bufs == NULL)
-				continue;
-
-			hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff);
-			buf = *bufs + samples_to_bytes(runtime, off);
-			if (copy_to_user(buf, hwbuf, samples_to_bytes(runtime, frames)))
-				return -EFAULT;
-		}
+	int err;
+
+	if (bufs == NULL)
+		return -EINVAL;
+
+	for (c = 0; c < channels; ++c) {
+		if (bufs[c] == NULL)
+			continue;
+
+		buf = bufs[c] + samples_to_bytes(runtime, off);
+		err = substream->ops->copy(substream, c, hwoff, buf, frames);
+		if (err < 0)
+			return err;
 	}
+
 	return 0;
 }
  
-- 
2.11.0



More information about the Alsa-devel mailing list