summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2012-10-31 16:35:30 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-12-03 12:59:13 -0800
commit08dc993050ecc2e664462ee61cc4dc3719aaa9c0 (patch)
treed8576d1d1eb7b19335f0bf150ffd78ae360d56b3
parent14de2f67dd5e58aa2b9b7df3cd445bb59cbe7d61 (diff)
ALSA: ua101, usx2y: fix broken MIDI output
commit e99ddfde6ae0dd2662bb40435696002b590e4057 upstream. Commit 88a8516a2128 (ALSA: usbaudio: implement USB autosuspend) added autosuspend code to all files making up the snd-usb-audio driver. However, midi.c is part of snd-usb-lib and is also used by other drivers, not all of which support autosuspend. Thus, calls to usb_autopm_get_interface() could fail, and this unexpected error would result in the MIDI output being completely unusable. Make it work by ignoring the error that is expected with drivers that do not support autosuspend. Reported-by: Colin Fletcher <colin.m.fletcher@googlemail.com> Reported-by: Devin Venable <venable.devin@gmail.com> Reported-by: Dr Nick Bailey <nicholas.bailey@glasgow.ac.uk> Reported-by: Jannis Achstetter <jannis_achstetter@web.de> Reported-by: Rui Nuno Capela <rncbc@rncbc.org> Cc: Oliver Neukum <oliver@neukum.org> Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--sound/usb/midi.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index f9289102886a..a0fe5dd3057c 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -147,6 +147,7 @@ struct snd_usb_midi_out_endpoint {
struct snd_usb_midi_out_endpoint* ep;
struct snd_rawmidi_substream *substream;
int active;
+ bool autopm_reference;
uint8_t cable; /* cable number << 4 */
uint8_t state;
#define STATE_UNKNOWN 0
@@ -1059,7 +1060,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
return -ENXIO;
}
err = usb_autopm_get_interface(umidi->iface);
- if (err < 0)
+ port->autopm_reference = err >= 0;
+ if (err < 0 && err != -EACCES)
return -EIO;
substream->runtime->private_data = port;
port->state = STATE_UNKNOWN;
@@ -1070,9 +1072,11 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
{
struct snd_usb_midi* umidi = substream->rmidi->private_data;
+ struct usbmidi_out_port *port = substream->runtime->private_data;
substream_open(substream, 0);
- usb_autopm_put_interface(umidi->iface);
+ if (port->autopm_reference)
+ usb_autopm_put_interface(umidi->iface);
return 0;
}