Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: pcm: Improved XRUN handling for indirect PCM helpers

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").

Link: https://lore.kernel.org/r/20230323065237.5062-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+16 -6
+16 -6
include/sound/pcm-indirect.h
··· 44 44 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) 45 45 diff += runtime->boundary; 46 46 if (diff < 0) 47 - return -EINVAL; 47 + return -EPIPE; 48 48 rec->sw_ready += (int)frames_to_bytes(runtime, diff); 49 49 rec->appl_ptr = appl_ptr; 50 50 } ··· 83 83 struct snd_pcm_indirect *rec, unsigned int ptr) 84 84 { 85 85 int bytes = ptr - rec->hw_io; 86 + int err; 87 + 86 88 if (bytes < 0) 87 89 bytes += rec->hw_buffer_size; 88 90 rec->hw_io = ptr; ··· 92 90 rec->sw_io += bytes; 93 91 if (rec->sw_io >= rec->sw_buffer_size) 94 92 rec->sw_io -= rec->sw_buffer_size; 95 - if (substream->ops->ack) 96 - substream->ops->ack(substream); 93 + if (substream->ops->ack) { 94 + err = substream->ops->ack(substream); 95 + if (err == -EPIPE) 96 + return SNDRV_PCM_POS_XRUN; 97 + } 97 98 return bytes_to_frames(substream->runtime, rec->sw_io); 98 99 } 99 100 ··· 117 112 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) 118 113 diff += runtime->boundary; 119 114 if (diff < 0) 120 - return -EINVAL; 115 + return -EPIPE; 121 116 rec->sw_ready -= frames_to_bytes(runtime, diff); 122 117 rec->appl_ptr = appl_ptr; 123 118 } ··· 157 152 { 158 153 int qsize; 159 154 int bytes = ptr - rec->hw_io; 155 + int err; 156 + 160 157 if (bytes < 0) 161 158 bytes += rec->hw_buffer_size; 162 159 rec->hw_io = ptr; ··· 169 162 rec->sw_io += bytes; 170 163 if (rec->sw_io >= rec->sw_buffer_size) 171 164 rec->sw_io -= rec->sw_buffer_size; 172 - if (substream->ops->ack) 173 - substream->ops->ack(substream); 165 + if (substream->ops->ack) { 166 + err = substream->ops->ack(substream); 167 + if (err == -EPIPE) 168 + return SNDRV_PCM_POS_XRUN; 169 + } 174 170 return bytes_to_frames(substream->runtime, rec->sw_io); 175 171 } 176 172