At Sun, 18 Nov 2012 17:58:00 +0100, Clemens Ladisch wrote:
The following change since commit a0d271cbfed1dd50278c6b06bead3d00ba0a88f9:
Linux 3.6 (2012-09-30 16:47:46 -0700)
is available in the git repository at:
git://git.alsa-project.org/alsa-kprivate.git usb-midi-fix-3.7
for you to fetch up to e99ddfde6ae0dd2662bb40435696002b590e4057:
ALSA: ua101, usx2y: fix broken MIDI output (2012-11-18 17:15:24 +0100)
ALSA: ua101, usx2y: fix broken MIDI output
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 Cc: 2.6.39+ stable@vger.kernel.org Signed-off-by: Clemens Ladisch clemens@ladisch.de
Thanks, pulled now.
Takashi
sound/usb/midi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index c83f614..eeefbce 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -148,6 +148,7 @@ struct snd_usb_midi_out_endpoint { struct snd_usb_midi_out_endpoint* ep; struct snd_rawmidi_substream *substream; int active;
uint8_t cable; /* cable number << 4 */ uint8_t state;bool autopm_reference;
#define STATE_UNKNOWN 0 @@ -1076,7 +1077,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;
@@ -1087,9 +1089,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)
return 0;usb_autopm_put_interface(umidi->iface);
}