[PATCH 1/3] ALSA: pcm: Improved XRUN handling for indirect PCM helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As PCM ack callback may handle the XRUN situation gracefully now,
change the indirect PCM helpers to give a proper error (-EPIPE).
Also, change the pointer callback helpers to deal with the XRUN error
properly, too.

This requires the PCM core change by the commit 8c721c53dda5
("ALSA: usb-audio: Fix recursive locking at XRUN during syncing").

Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
---
 include/sound/pcm-indirect.h | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/include/sound/pcm-indirect.h b/include/sound/pcm-indirect.h
index 04127686e8d0..98e06ea73b2b 100644
--- a/include/sound/pcm-indirect.h
+++ b/include/sound/pcm-indirect.h
@@ -44,7 +44,7 @@ snd_pcm_indirect_playback_transfer(struct snd_pcm_substream *substream,
 		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
 			diff += runtime->boundary;
 		if (diff < 0)
-			return -EINVAL;
+			return -EPIPE;
 		rec->sw_ready += (int)frames_to_bytes(runtime, diff);
 		rec->appl_ptr = appl_ptr;
 	}
@@ -83,6 +83,8 @@ snd_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream,
 				  struct snd_pcm_indirect *rec, unsigned int ptr)
 {
 	int bytes = ptr - rec->hw_io;
+	int err;
+
 	if (bytes < 0)
 		bytes += rec->hw_buffer_size;
 	rec->hw_io = ptr;
@@ -90,8 +92,11 @@ snd_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream,
 	rec->sw_io += bytes;
 	if (rec->sw_io >= rec->sw_buffer_size)
 		rec->sw_io -= rec->sw_buffer_size;
-	if (substream->ops->ack)
-		substream->ops->ack(substream);
+	if (substream->ops->ack) {
+		err = substream->ops->ack(substream);
+		if (err == -EPIPE)
+			return SNDRV_PCM_POS_XRUN;
+	}
 	return bytes_to_frames(substream->runtime, rec->sw_io);
 }
 
@@ -112,7 +117,7 @@ snd_pcm_indirect_capture_transfer(struct snd_pcm_substream *substream,
 		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
 			diff += runtime->boundary;
 		if (diff < 0)
-			return -EINVAL;
+			return -EPIPE;
 		rec->sw_ready -= frames_to_bytes(runtime, diff);
 		rec->appl_ptr = appl_ptr;
 	}
@@ -152,6 +157,8 @@ snd_pcm_indirect_capture_pointer(struct snd_pcm_substream *substream,
 {
 	int qsize;
 	int bytes = ptr - rec->hw_io;
+	int err;
+
 	if (bytes < 0)
 		bytes += rec->hw_buffer_size;
 	rec->hw_io = ptr;
@@ -162,8 +169,11 @@ snd_pcm_indirect_capture_pointer(struct snd_pcm_substream *substream,
 	rec->sw_io += bytes;
 	if (rec->sw_io >= rec->sw_buffer_size)
 		rec->sw_io -= rec->sw_buffer_size;
-	if (substream->ops->ack)
-		substream->ops->ack(substream);
+	if (substream->ops->ack) {
+		err = substream->ops->ack(substream);
+		if (err == -EPIPE)
+			return SNDRV_PCM_POS_XRUN;
+	}
 	return bytes_to_frames(substream->runtime, rec->sw_io);
 }
 
-- 
2.35.3




[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux