Skip to content

Commit

Permalink
ALSA: usb-audio: Respond to suspend and resume callbacks for MIDI input
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
agoode authored and tiwai committed Aug 5, 2014
1 parent 81cb6b6 commit f7881e5
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
9 changes: 9 additions & 0 deletions sound/usb/card.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
struct snd_usb_audio *chip = usb_get_intfdata(intf);
struct snd_usb_stream *as;
struct usb_mixer_interface *mixer;
struct list_head *p;

if (chip == (void *)-1L)
return 0;
Expand All @@ -692,6 +693,9 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
as->substream[0].need_setup_ep =
as->substream[1].need_setup_ep = true;
}
list_for_each(p, &chip->midi_list) {
snd_usbmidi_suspend(p);
}
}
} else {
/*
Expand All @@ -713,6 +717,7 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
{
struct snd_usb_audio *chip = usb_get_intfdata(intf);
struct usb_mixer_interface *mixer;
struct list_head *p;
int err = 0;

if (chip == (void *)-1L)
Expand All @@ -731,6 +736,10 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
goto err_out;
}

list_for_each(p, &chip->midi_list) {
snd_usbmidi_resume(p);
}

if (!chip->autosuspended)
snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
chip->autosuspended = 0;
Expand Down
28 changes: 28 additions & 0 deletions sound/usb/midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2186,6 +2186,34 @@ void snd_usbmidi_input_start(struct list_head* p)
}
EXPORT_SYMBOL(snd_usbmidi_input_start);

/*
* Prepare for suspend. Typically called from the USB suspend callback.
*/
void snd_usbmidi_suspend(struct list_head *p)
{
struct snd_usb_midi *umidi;

umidi = list_entry(p, struct snd_usb_midi, list);
mutex_lock(&umidi->mutex);
snd_usbmidi_input_stop(p);
mutex_unlock(&umidi->mutex);
}
EXPORT_SYMBOL(snd_usbmidi_suspend);

/*
* Resume. Typically called from the USB resume callback.
*/
void snd_usbmidi_resume(struct list_head *p)
{
struct snd_usb_midi *umidi;

umidi = list_entry(p, struct snd_usb_midi, list);
mutex_lock(&umidi->mutex);
snd_usbmidi_input_start(p);
mutex_unlock(&umidi->mutex);
}
EXPORT_SYMBOL(snd_usbmidi_resume);

/*
* Creates and registers everything needed for a MIDI streaming interface.
*/
Expand Down
2 changes: 2 additions & 0 deletions sound/usb/midi.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,7 @@ int snd_usbmidi_create(struct snd_card *card,
void snd_usbmidi_input_stop(struct list_head* p);
void snd_usbmidi_input_start(struct list_head* p);
void snd_usbmidi_disconnect(struct list_head *p);
void snd_usbmidi_suspend(struct list_head *p);
void snd_usbmidi_resume(struct list_head *p);

#endif /* __USBMIDI_H */

0 comments on commit f7881e5

Please sign in to comment.