Skip to content

Commit 8269789

Browse files
CassivsGabriellisgregkh
authored andcommitted
ALSA: usb-audio: midi2: Restart output URBs on resume
commit f3c57c9 upstream. USB MIDI 2.0 suspend saves the endpoint running state, clears it and kills all endpoint URBs. Resume restores the running state, but only restarts input endpoints. For a running output endpoint, this leaves the endpoint marked running with an empty URB queue. Output transfer progress depends on either the rawmidi trigger path starting the queue or an output completion refilling it. After suspend there is no completion left, and output data that remains queued in the raw UMP or legacy rawmidi buffer can stay stalled until userspace happens to trigger the stream again. Restore the saved state with atomic accessors, keep input endpoints restarted as before, and restart output endpoints that were running before suspend. Clear the saved suspend state after restoring it. Fixes: ff49d1d ("ALSA: usb-audio: USB MIDI 2.0 UMP support") Cc: stable@vger.kernel.org Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Link: https://patch.msgid.link/20260504-usb-midi2-output-resume-v1-1-c089cc8ad3c6@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a502b99 commit 8269789

1 file changed

Lines changed: 5 additions & 4 deletions

File tree

sound/usb/midi2.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ static void kill_midi_urbs(struct snd_usb_midi2_endpoint *ep, bool suspending)
234234
if (!ep)
235235
return;
236236
if (suspending)
237-
ep->suspended = ep->running;
237+
atomic_set(&ep->suspended, atomic_read(&ep->running));
238238
atomic_set(&ep->running, 0);
239239
for (i = 0; i < ep->num_urbs; i++) {
240240
if (!ep->urbs[i].urb)
@@ -1197,10 +1197,11 @@ void snd_usb_midi_v2_suspend_all(struct snd_usb_audio *chip)
11971197

11981198
static void resume_midi2_endpoint(struct snd_usb_midi2_endpoint *ep)
11991199
{
1200-
ep->running = ep->suspended;
1201-
if (ep->direction == STR_IN)
1200+
atomic_set(&ep->running, atomic_read(&ep->suspended));
1201+
atomic_set(&ep->suspended, 0);
1202+
1203+
if (ep->direction == STR_IN || atomic_read(&ep->running))
12021204
submit_io_urbs(ep);
1203-
/* FIXME: does it all? */
12041205
}
12051206

12061207
void snd_usb_midi_v2_resume_all(struct snd_usb_audio *chip)

0 commit comments

Comments
 (0)