From ea57e8743e22cd0645f74c55db96f9c98c0ccda2 Mon Sep 17 00:00:00 2001 From: gushengxian Date: Mon, 5 Jul 2021 02:34:19 -0700 Subject: ALSA: usx2y: fix spelling mistakes Fix some spelling mistakes as follows: wroong ==> wrong evrything ==> everything Signed-off-by: gushengxian Link: https://lore.kernel.org/r/20210705093419.664366-1-gushengxian507419@gmail.com Signed-off-by: Takashi Iwai --- sound/usb/usx2y/usbusx2yaudio.c | 2 +- sound/usb/usx2y/usx2yhwdeppcm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/usb') diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 6154662d3097..c39cc6851e2d 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -526,7 +526,7 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs) cleanup: if (err) { usx2y_subs_startup_finish(usx2y); - usx2y_clients_stop(usx2y); // something is completely wroong > stop evrything + usx2y_clients_stop(usx2y); // something is completely wrong > stop everything } return err; } diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index da643c2dbb12..db83522c1b49 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c @@ -480,7 +480,7 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) cleanup: if (err) { usx2y_subs_startup_finish(usx2y); // Call it now - usx2y_clients_stop(usx2y); // something is completely wroong > stop evrything + usx2y_clients_stop(usx2y); // something is completely wrong > stop everything } return err; } -- cgit v1.2.3 From ff630b6ab952416bb52ab3528001fe4eb8e7dac7 Mon Sep 17 00:00:00 2001 From: gushengxian Date: Mon, 5 Jul 2021 05:00:52 -0700 Subject: ALSA: usb-audio: fix spelling mistakes Fix some spelling mistakes as follows: altenate ==> alternate compatbile ==> compatible perfoms ==> performs dont'register ==> don't register periodicaly ==> periodically arount ==> around Signed-off-by: gushengxian Link: https://lore.kernel.org/r/20210705120052.665212-1-gushengxian507419@gmail.com Signed-off-by: Takashi Iwai --- sound/usb/card.h | 2 +- sound/usb/endpoint.c | 4 ++-- sound/usb/media.c | 2 +- sound/usb/mixer_s1810c.c | 2 +- sound/usb/mixer_scarlett.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'sound/usb') diff --git a/sound/usb/card.h b/sound/usb/card.h index 5577a776561b..f41dbdc31336 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -19,7 +19,7 @@ struct audioformat { unsigned char iface; /* interface number */ unsigned char altsetting; /* corresponding alternate setting */ unsigned char ep_idx; /* endpoint array index */ - unsigned char altset_idx; /* array index of altenate setting */ + unsigned char altset_idx; /* array index of alternate setting */ unsigned char attributes; /* corresponding attributes of cs endpoint */ unsigned char endpoint; /* endpoint */ unsigned char ep_attr; /* endpoint attributes */ diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index da649211bff3..4f856771216b 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -645,7 +645,7 @@ static bool endpoint_compatible(struct snd_usb_endpoint *ep, } /* - * Check whether the given fp and hw params are compatbile with the current + * Check whether the given fp and hw params are compatible with the current * setup of the target EP for implicit feedback sync */ bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip, @@ -1245,7 +1245,7 @@ static int snd_usb_endpoint_set_params(struct snd_usb_audio *chip, * * This function sets up the EP to be fully usable state. * It's called either from hw_params or prepare callback. - * The function checks need_setup flag, and perfoms nothing unless needed, + * The function checks need_setup flag, and performs nothing unless needed, * so it's safe to call this multiple times. * * This returns zero if unchanged, 1 if the configuration has changed, diff --git a/sound/usb/media.c b/sound/usb/media.c index 812017eacbcf..840f42cb9272 100644 --- a/sound/usb/media.c +++ b/sound/usb/media.c @@ -285,7 +285,7 @@ snd_mixer_init: ret); if (!media_devnode_is_registered(mdev->devnode)) { - /* dont'register if snd_media_mixer_init() failed */ + /* don't register if snd_media_mixer_init() failed */ if (ret) goto create_fail; diff --git a/sound/usb/mixer_s1810c.c b/sound/usb/mixer_s1810c.c index c53a9773f310..0255089c9efb 100644 --- a/sound/usb/mixer_s1810c.c +++ b/sound/usb/mixer_s1810c.c @@ -163,7 +163,7 @@ snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 a, } /* - * When opening Universal Control the program periodicaly + * When opening Universal Control the program periodically * sends and receives state packets for syncinc state between * the device and the host. * diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c index 691b95466d0f..0d6e4f15bf77 100644 --- a/sound/usb/mixer_scarlett.c +++ b/sound/usb/mixer_scarlett.c @@ -21,7 +21,7 @@ * Auto-detection via UAC2 is not feasible to properly discover the vast * majority of features. It's related to both Linux/ALSA's UAC2 as well as * Focusrite's implementation of it. Eventually quirks may be sufficient but - * right now it's a major headache to work arount these things. + * right now it's a major headache to work around these things. * * NB. Neither the OSX nor the win driver provided by Focusrite performs * discovery, they seem to operate the same as this driver. -- cgit v1.2.3 From 307cc9baac5c07b23da78d75c3d4755e9cffab26 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 7 Jul 2021 13:24:47 +0200 Subject: ALSA: usb-audio: Reduce latency at playback start, take#2 This is another attempt for the reduction of the latency at the start of a USB audio playback stream. The first attempt in the commit 9ce650a75a3b caused an unexpected regression (a deadlock with pipewire usage) and was later reverted by the commit 4b820e167bf6. The devils are always living in details, of course; the cause of the deadlock was the call of snd_pcm_period_elapsed() inside prepare_playback_urb() callback. In the original code, this callback is never called from the stream lock context as it's driven solely from the URB complete callback. Along with the movement of the URB submission into the trigger START, this prepare call may be also executed in the stream lock context, hence it deadlocked with the another lock in snd_pcm_period_elapsed(). (Note that this happens only conditionally with a small period size that matches with the URB buffer length, which was a reason I overlooked during my tests. Also, the problem wasn't seen in the capture stream because the capture stream handles the period-elapsed only at retire callback that isn't executed at the trigger.) If it were only about avoiding the deadlock, it'd be possible to use snd_pcm_period_elapsed_under_stream_lock() as a solution. However, in general, the period elapsed notification must be sent after the actual stream start, and replacing the call wouldn't satisfy the pattern. A better option is to delay the notification after the stream start procedure finished, instead. In the case of USB framework, one of the fitting place would be the complete callback of the first URB. So, as a workaround of the deadlock and the order fixes above, in addition to the re-applying the changes in the commit 9ce650a75a3, this patch introduces a new flag indicating the delayed period-elapsed handling and sets it under the possible deadlock condition (i.e. prepare callback being called before subs->running is set). Once when the flag is set, the period-elapsed call is handled at a later URB complete call instead. As a reference for the original motivation for the low-latency change, I cite here again: | USB-audio driver behaves a bit strangely for the playback stream -- | namely, it starts sending silent packets at PCM prepare state while | the actual data is submitted at first when the trigger START is | kicked off. This is a workaround for the behavior where URBs are | processed too quickly at the beginning. That is, if we start | submitting URBs at trigger START, the first few URBs will be | immediately completed, and this would result in the immediate | period-elapsed calls right after the start, which may confuse | applications. | | OTOH, submitting the data after silent URBs would, of course, result | in a certain delay of the actual data processing, and this is rather | more serious problem on modern systems, in practice. | | This patch tries to revert the workaround and lets the URB | submission starting at PCM trigger for the playback again. As far | as I've tested with various backends (native ALSA, PA, JACK, PW), I | haven't seen any problems (famous last words :) | | Note that the capture stream handling needs no such workaround, | since the capture is driven per received URB. Link: https://lore.kernel.org/r/4e71531f-4535-fd46-040e-506a3c256bbd@marcan.st Link: https://lore.kernel.org/r/s5hbl7li0fe.wl-tiwai@suse.de Signed-off-by: Takashi Iwai Link: https://lore.kernel.org/r/20210707112447.27485-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/usb/card.h | 1 + sound/usb/pcm.c | 26 +++++++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'sound/usb') diff --git a/sound/usb/card.h b/sound/usb/card.h index f41dbdc31336..6c0a052a28f9 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -158,6 +158,7 @@ struct snd_usb_substream { unsigned int stream_offset_adj; /* Bytes to drop from beginning of stream (for non-compliant devices) */ unsigned int running: 1; /* running status */ + unsigned int period_elapsed_pending; /* delay period handling */ unsigned int buffer_bytes; /* buffer size in bytes */ unsigned int inflight_bytes; /* in-flight data bytes on buffer (for playback) */ diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index e26d37365f02..4e5031a68064 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -611,13 +611,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) subs->hwptr_done = 0; subs->transfer_done = 0; subs->last_frame_number = 0; + subs->period_elapsed_pending = 0; runtime->delay = 0; - /* for playback, submit the URBs now; otherwise, the first hwptr_done - * updates for all URBs would happen at the same time when starting */ - if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) - ret = start_endpoints(subs); - unlock: snd_usb_unlock_shutdown(chip); return ret; @@ -1398,6 +1394,10 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, subs->trigger_tstamp_pending_update = false; } + if (period_elapsed && !subs->running) { + subs->period_elapsed_pending = 1; + period_elapsed = 0; + } spin_unlock_irqrestore(&subs->lock, flags); urb->transfer_buffer_length = bytes; if (period_elapsed) @@ -1413,6 +1413,7 @@ static void retire_playback_urb(struct snd_usb_substream *subs, { unsigned long flags; struct snd_urb_ctx *ctx = urb->context; + bool period_elapsed = false; spin_lock_irqsave(&subs->lock, flags); if (ctx->queued) { @@ -1423,13 +1424,20 @@ static void retire_playback_urb(struct snd_usb_substream *subs, } 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); } static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_usb_substream *subs = substream->runtime->private_data; + int err; switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -1440,6 +1448,14 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea prepare_playback_urb, retire_playback_urb, subs); + if (cmd == SNDRV_PCM_TRIGGER_START) { + err = start_endpoints(subs); + if (err < 0) { + snd_usb_endpoint_set_callback(subs->data_endpoint, + NULL, NULL, NULL); + return err; + } + } subs->running = 1; dev_dbg(&subs->dev->dev, "%d:%d Start Playback PCM\n", subs->cur_audiofmt->iface, -- cgit v1.2.3