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

ALSA: usb-audio: Respond to suspend and resume callbacks for MIDI input

sound/usb/card.c registers USB suspend and resume but did not previously
kill the input URBs. This means that USB MIDI devices left open across
suspend/resume had non-functional input (output still usually worked,
but it looks like that is another issue). Before this change, we would
get ESHUTDOWN for each of the input URBs at suspend time, killing input.

Signed-off-by: Adam Goode <agoode@google.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Adam Goode and committed by
Takashi Iwai
f7881e5e 81cb6b6b

+39
+9
sound/usb/card.c
··· 680 680 struct snd_usb_audio *chip = usb_get_intfdata(intf); 681 681 struct snd_usb_stream *as; 682 682 struct usb_mixer_interface *mixer; 683 + struct list_head *p; 683 684 684 685 if (chip == (void *)-1L) 685 686 return 0; ··· 692 691 snd_pcm_suspend_all(as->pcm); 693 692 as->substream[0].need_setup_ep = 694 693 as->substream[1].need_setup_ep = true; 694 + } 695 + list_for_each(p, &chip->midi_list) { 696 + snd_usbmidi_suspend(p); 695 697 } 696 698 } 697 699 } else { ··· 717 713 { 718 714 struct snd_usb_audio *chip = usb_get_intfdata(intf); 719 715 struct usb_mixer_interface *mixer; 716 + struct list_head *p; 720 717 int err = 0; 721 718 722 719 if (chip == (void *)-1L) ··· 734 729 err = snd_usb_mixer_resume(mixer, reset_resume); 735 730 if (err < 0) 736 731 goto err_out; 732 + } 733 + 734 + list_for_each(p, &chip->midi_list) { 735 + snd_usbmidi_resume(p); 737 736 } 738 737 739 738 if (!chip->autosuspended)
+28
sound/usb/midi.c
··· 2187 2187 EXPORT_SYMBOL(snd_usbmidi_input_start); 2188 2188 2189 2189 /* 2190 + * Prepare for suspend. Typically called from the USB suspend callback. 2191 + */ 2192 + void snd_usbmidi_suspend(struct list_head *p) 2193 + { 2194 + struct snd_usb_midi *umidi; 2195 + 2196 + umidi = list_entry(p, struct snd_usb_midi, list); 2197 + mutex_lock(&umidi->mutex); 2198 + snd_usbmidi_input_stop(p); 2199 + mutex_unlock(&umidi->mutex); 2200 + } 2201 + EXPORT_SYMBOL(snd_usbmidi_suspend); 2202 + 2203 + /* 2204 + * Resume. Typically called from the USB resume callback. 2205 + */ 2206 + void snd_usbmidi_resume(struct list_head *p) 2207 + { 2208 + struct snd_usb_midi *umidi; 2209 + 2210 + umidi = list_entry(p, struct snd_usb_midi, list); 2211 + mutex_lock(&umidi->mutex); 2212 + snd_usbmidi_input_start(p); 2213 + mutex_unlock(&umidi->mutex); 2214 + } 2215 + EXPORT_SYMBOL(snd_usbmidi_resume); 2216 + 2217 + /* 2190 2218 * Creates and registers everything needed for a MIDI streaming interface. 2191 2219 */ 2192 2220 int snd_usbmidi_create(struct snd_card *card,
+2
sound/usb/midi.h
··· 46 46 void snd_usbmidi_input_stop(struct list_head* p); 47 47 void snd_usbmidi_input_start(struct list_head* p); 48 48 void snd_usbmidi_disconnect(struct list_head *p); 49 + void snd_usbmidi_suspend(struct list_head *p); 50 + void snd_usbmidi_resume(struct list_head *p); 49 51 50 52 #endif /* __USBMIDI_H */