diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2009-05-27 10:49:30 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-05-27 11:25:33 +0200 |
commit | 55de5ef970c680d8d75f2a9aa7e4f172140dbd9c (patch) | |
tree | 3fed0a032ccc3050ceacbe4f230d1c02cd122f1c /sound/usb/usbmidi.c | |
parent | 59a3759d0fe8d969888c741bb33f4946e4d3750d (diff) | |
download | op-kernel-dev-55de5ef970c680d8d75f2a9aa7e4f172140dbd9c.zip op-kernel-dev-55de5ef970c680d8d75f2a9aa7e4f172140dbd9c.tar.gz |
sound: usb-audio: make the MotU Fastlane work again
Kernel 2.6.18 broke the MotU Fastlane, which uses duplicate endpoint
numbers in a manner that is not only illegal but also confuses the
kernel's endpoint descriptor caching mechanism. To work around this, we
have to add a separate usb_set_interface() call to guide the USB core to
the correct descriptors.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Reported-and-tested-by: David Fries <david@fries.net>
Cc: <stable@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/usbmidi.c')
-rw-r--r-- | sound/usb/usbmidi.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 26bad37..2fb35cc 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -1778,8 +1778,18 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); break; - case QUIRK_MIDI_RAW: + case QUIRK_MIDI_FASTLANE: umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; + /* + * Interface 1 contains isochronous endpoints, but with the same + * numbers as in interface 0. Since it is interface 1 that the + * USB core has most recently seen, these descriptors are now + * associated with the endpoint numbers. This will foul up our + * attempts to submit bulk/interrupt URBs to the endpoints in + * interface 0, so we have to make sure that the USB core looks + * again at interface 0 by calling usb_set_interface() on it. + */ + usb_set_interface(umidi->chip->dev, 0, 0); err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); break; case QUIRK_MIDI_EMAGIC: |