Commit e99ddfde authored by Clemens Ladisch's avatar Clemens Ladisch

ALSA: ua101, usx2y: fix broken MIDI output

Commit 88a8516a (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: default avatarColin Fletcher <colin.m.fletcher@googlemail.com>
Reported-by: default avatarDevin Venable <venable.devin@gmail.com>
Reported-by: default avatarDr Nick Bailey <nicholas.bailey@glasgow.ac.uk>
Reported-by: default avatarJannis Achstetter <jannis_achstetter@web.de>
Reported-by: default avatarRui Nuno Capela <rncbc@rncbc.org>
Cc: Oliver Neukum <oliver@neukum.org>
Cc: 2.6.39+ <stable@vger.kernel.org>
Signed-off-by: default avatarClemens Ladisch <clemens@ladisch.de>
parent a0d271cb
...@@ -148,6 +148,7 @@ struct snd_usb_midi_out_endpoint { ...@@ -148,6 +148,7 @@ struct snd_usb_midi_out_endpoint {
struct snd_usb_midi_out_endpoint* ep; struct snd_usb_midi_out_endpoint* ep;
struct snd_rawmidi_substream *substream; struct snd_rawmidi_substream *substream;
int active; int active;
bool autopm_reference;
uint8_t cable; /* cable number << 4 */ uint8_t cable; /* cable number << 4 */
uint8_t state; uint8_t state;
#define STATE_UNKNOWN 0 #define STATE_UNKNOWN 0
...@@ -1076,7 +1077,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) ...@@ -1076,7 +1077,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
return -ENXIO; return -ENXIO;
} }
err = usb_autopm_get_interface(umidi->iface); err = usb_autopm_get_interface(umidi->iface);
if (err < 0) port->autopm_reference = err >= 0;
if (err < 0 && err != -EACCES)
return -EIO; return -EIO;
substream->runtime->private_data = port; substream->runtime->private_data = port;
port->state = STATE_UNKNOWN; port->state = STATE_UNKNOWN;
...@@ -1087,8 +1089,10 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) ...@@ -1087,8 +1089,10 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
static int snd_usbmidi_output_close(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 snd_usb_midi* umidi = substream->rmidi->private_data;
struct usbmidi_out_port *port = substream->runtime->private_data;
substream_open(substream, 0); substream_open(substream, 0);
if (port->autopm_reference)
usb_autopm_put_interface(umidi->iface); usb_autopm_put_interface(umidi->iface);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment