mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 16:53:49 +00:00
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 8c721c53dd
("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>
This commit is contained in:
parent
a7a0dcdff4
commit
0146878cf2
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user