diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2009-05-27 10:49:30 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-11 20:01:30 -0700 |
commit | 3e29e7c674d1197a919b2d91134569caa7e79484 (patch) | |
tree | f35427656a8b2b2a732c73ade488d70f2969aae5 | |
parent | 894e24c2c5b6055ef9704b0ffdbacd9d4fdd130b (diff) |
sound: usb-audio: make the MotU Fastlane work again
commit 55de5ef970c680d8d75f2a9aa7e4f172140dbd9c upstream.
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>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | sound/usb/usbaudio.c | 2 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 2 | ||||
-rw-r--r-- | sound/usb/usbmidi.c | 12 | ||||
-rw-r--r-- | sound/usb/usbquirks.h | 2 |
4 files changed, 14 insertions, 4 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 17106233b60..c10e476226c 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -3367,7 +3367,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip, [QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface, [QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface, [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, - [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, + [QUIRK_MIDI_FASTLANE] = snd_usb_create_midi_interface, [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 7cf18c38dc4..7191d8270c4 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -153,7 +153,7 @@ enum quirk_type { QUIRK_MIDI_YAMAHA, QUIRK_MIDI_MIDIMAN, QUIRK_MIDI_NOVATION, - QUIRK_MIDI_RAW, + QUIRK_MIDI_FASTLANE, QUIRK_MIDI_EMAGIC, QUIRK_MIDI_CME, QUIRK_AUDIO_STANDARD_INTERFACE, diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 940ae5a2258..cd2b6222e43 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -1733,8 +1733,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: diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 9ea726c049c..076ca4c67cc 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -1756,7 +1756,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), .data = & (const struct snd_usb_audio_quirk[]) { { .ifnum = 0, - .type = QUIRK_MIDI_RAW + .type = QUIRK_MIDI_FASTLANE }, { .ifnum = 1, |