From 55de5ef970c680d8d75f2a9aa7e4f172140dbd9c Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 27 May 2009 10:49:30 +0200 Subject: 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 Reported-and-tested-by: David Fries Cc: Signed-off-by: Takashi Iwai --- sound/usb/usbaudio.c | 2 +- sound/usb/usbaudio.h | 2 +- sound/usb/usbmidi.c | 12 +++++++++++- sound/usb/usbquirks.h | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 823296d..a6b8848 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -3347,7 +3347,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 36e4f7a2..8e7f789 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_MIDI_US122L, 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: diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 647ef50..5d955aa 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -1868,7 +1868,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), .data = & (const struct snd_usb_audio_quirk[]) { { .ifnum = 0, - .type = QUIRK_MIDI_RAW + .type = QUIRK_MIDI_FASTLANE }, { .ifnum = 1, -- cgit v1.1