ALSA: usb-audio: Use guard() for spin locks

Clean up the code using guard() for spin locks.

Merely code refactoring, and no behavior change.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai
2025-09-10 13:09:26 +02:00
parent d532322732
commit 02d0aba676

View File

@@ -1528,8 +1528,6 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
int counts;
unsigned int transfer_done, frame_limit, avail = 0;
int i, stride, period_elapsed = 0;
unsigned long flags;
int err = 0;
stride = ep->stride;
@@ -1537,106 +1535,101 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
ctx->queued = 0;
urb->number_of_packets = 0;
spin_lock_irqsave(&subs->lock, flags);
frame_limit = subs->frame_limit + ep->max_urb_frames;
transfer_done = subs->transfer_done;
scoped_guard(spinlock_irqsave, &subs->lock) {
frame_limit = subs->frame_limit + ep->max_urb_frames;
transfer_done = subs->transfer_done;
if (subs->lowlatency_playback &&
runtime->state != SNDRV_PCM_STATE_DRAINING) {
unsigned int hwptr = subs->hwptr_done / stride;
if (subs->lowlatency_playback &&
runtime->state != SNDRV_PCM_STATE_DRAINING) {
unsigned int hwptr = subs->hwptr_done / stride;
/* calculate the byte offset-in-buffer of the appl_ptr */
avail = (runtime->control->appl_ptr - runtime->hw_ptr_base)
% runtime->buffer_size;
if (avail <= hwptr)
avail += runtime->buffer_size;
avail -= hwptr;
}
for (i = 0; i < ctx->packets; i++) {
counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, avail);
if (counts < 0)
break;
/* set up descriptor */
urb->iso_frame_desc[i].offset = frames * stride;
urb->iso_frame_desc[i].length = counts * stride;
frames += counts;
avail -= counts;
urb->number_of_packets++;
transfer_done += counts;
if (transfer_done >= runtime->period_size) {
transfer_done -= runtime->period_size;
frame_limit = 0;
period_elapsed = 1;
if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
if (transfer_done > 0) {
/* FIXME: fill-max mode is not
* supported yet */
frames -= transfer_done;
counts -= transfer_done;
urb->iso_frame_desc[i].length =
counts * stride;
transfer_done = 0;
}
i++;
if (i < ctx->packets) {
/* add a transfer delimiter */
urb->iso_frame_desc[i].offset =
frames * stride;
urb->iso_frame_desc[i].length = 0;
urb->number_of_packets++;
}
break;
}
/* calculate the byte offset-in-buffer of the appl_ptr */
avail = (runtime->control->appl_ptr - runtime->hw_ptr_base)
% runtime->buffer_size;
if (avail <= hwptr)
avail += runtime->buffer_size;
avail -= hwptr;
}
/* finish at the period boundary or after enough frames */
if ((period_elapsed || transfer_done >= frame_limit) &&
!snd_usb_endpoint_implicit_feedback_sink(ep))
break;
}
if (!frames) {
err = -EAGAIN;
goto unlock;
}
for (i = 0; i < ctx->packets; i++) {
counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, avail);
if (counts < 0)
break;
/* set up descriptor */
urb->iso_frame_desc[i].offset = frames * stride;
urb->iso_frame_desc[i].length = counts * stride;
frames += counts;
avail -= counts;
urb->number_of_packets++;
transfer_done += counts;
if (transfer_done >= runtime->period_size) {
transfer_done -= runtime->period_size;
frame_limit = 0;
period_elapsed = 1;
if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
if (transfer_done > 0) {
/* FIXME: fill-max mode is not
* supported yet */
frames -= transfer_done;
counts -= transfer_done;
urb->iso_frame_desc[i].length =
counts * stride;
transfer_done = 0;
}
i++;
if (i < ctx->packets) {
/* add a transfer delimiter */
urb->iso_frame_desc[i].offset =
frames * stride;
urb->iso_frame_desc[i].length = 0;
urb->number_of_packets++;
}
break;
}
}
/* finish at the period boundary or after enough frames */
if ((period_elapsed || transfer_done >= frame_limit) &&
!snd_usb_endpoint_implicit_feedback_sink(ep))
break;
}
bytes = frames * stride;
subs->transfer_done = transfer_done;
subs->frame_limit = frame_limit;
if (unlikely(ep->cur_format == SNDRV_PCM_FORMAT_DSD_U16_LE &&
subs->cur_audiofmt->dsd_dop)) {
fill_playback_urb_dsd_dop(subs, urb, bytes);
} else if (unlikely(ep->cur_format == SNDRV_PCM_FORMAT_DSD_U8 &&
subs->cur_audiofmt->dsd_bitrev)) {
fill_playback_urb_dsd_bitrev(subs, urb, bytes);
} else {
/* usual PCM */
if (!subs->tx_length_quirk)
copy_to_urb(subs, urb, 0, stride, bytes);
else
bytes = copy_to_urb_quirk(subs, urb, stride, bytes);
if (!frames)
return -EAGAIN;
bytes = frames * stride;
subs->transfer_done = transfer_done;
subs->frame_limit = frame_limit;
if (unlikely(ep->cur_format == SNDRV_PCM_FORMAT_DSD_U16_LE &&
subs->cur_audiofmt->dsd_dop)) {
fill_playback_urb_dsd_dop(subs, urb, bytes);
} else if (unlikely(ep->cur_format == SNDRV_PCM_FORMAT_DSD_U8 &&
subs->cur_audiofmt->dsd_bitrev)) {
fill_playback_urb_dsd_bitrev(subs, urb, bytes);
} else {
/* usual PCM */
if (!subs->tx_length_quirk)
copy_to_urb(subs, urb, 0, stride, bytes);
else
bytes = copy_to_urb_quirk(subs, urb, stride, bytes);
/* bytes is now amount of outgoing data */
}
subs->last_frame_number = usb_get_current_frame_number(subs->dev);
if (subs->trigger_tstamp_pending_update) {
/* this is the first actual URB submitted,
* update trigger timestamp to reflect actual start time
*/
snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
subs->trigger_tstamp_pending_update = false;
}
if (period_elapsed && !subs->running && subs->lowlatency_playback) {
subs->period_elapsed_pending = 1;
period_elapsed = 0;
}
}
subs->last_frame_number = usb_get_current_frame_number(subs->dev);
if (subs->trigger_tstamp_pending_update) {
/* this is the first actual URB submitted,
* update trigger timestamp to reflect actual start time
*/
snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
subs->trigger_tstamp_pending_update = false;
}
if (period_elapsed && !subs->running && subs->lowlatency_playback) {
subs->period_elapsed_pending = 1;
period_elapsed = 0;
}
unlock:
spin_unlock_irqrestore(&subs->lock, flags);
if (err < 0)
return err;
urb->transfer_buffer_length = bytes;
if (period_elapsed) {
if (in_stream_lock)
@@ -1654,24 +1647,23 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
static void retire_playback_urb(struct snd_usb_substream *subs,
struct urb *urb)
{
unsigned long flags;
struct snd_urb_ctx *ctx = urb->context;
bool period_elapsed = false;
spin_lock_irqsave(&subs->lock, flags);
if (ctx->queued) {
if (subs->inflight_bytes >= ctx->queued)
subs->inflight_bytes -= ctx->queued;
else
subs->inflight_bytes = 0;
}
scoped_guard(spinlock_irqsave, &subs->lock) {
if (ctx->queued) {
if (subs->inflight_bytes >= ctx->queued)
subs->inflight_bytes -= ctx->queued;
else
subs->inflight_bytes = 0;
}
subs->last_frame_number = usb_get_current_frame_number(subs->dev);
if (subs->running) {
period_elapsed = subs->period_elapsed_pending;
subs->period_elapsed_pending = 0;
subs->last_frame_number = usb_get_current_frame_number(subs->dev);
if (subs->running) {
period_elapsed = subs->period_elapsed_pending;
subs->period_elapsed_pending = 0;
}
}
spin_unlock_irqrestore(&subs->lock, flags);
if (period_elapsed)
snd_pcm_period_elapsed(subs->pcm_substream);
}