public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* bad endpoint address, MOTU FastLane
@ 2009-05-11 22:12 David Fries
  2009-05-12  7:55 ` Clemens Ladisch
  0 siblings, 1 reply; 9+ messages in thread
From: David Fries @ 2009-05-11 22:12 UTC (permalink / raw)
  To: David Griffith; +Cc: Andrew Morton, linux-kernel, linux-usb, todd

This is a USB Midi device.  The device used to work, David Griffith
from a previous e-mail lists 2.6.17 works 2.6.18 doesn't.  The USB
midi driver talks to it using interrupt transfers, it doesn't need the
Isoc transfers.  usb_submit_urb returns -22 EINVAL invalid argument as
it is trying to submit an interrupt packet to what is registered as an
isoc endpoint.  The second interface has the same end point addresses
as the first.  Any suggestions on how to deal with this class of
broken hardware?

T:  Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#=  2 Spd=12  MxCh= 0
D:  Ver= 1.00 Cls=ff(vend.) Sub=02 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=07fd ProdID=0001 Rev= 1.01
S:  Product=FastLane
C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 4 Cls=ff(vend.) Sub=04 Prot=ff Driver=(none)
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=1ms
E:  Ad=02(O) Atr=03(Int.) MxPS=   4 Ivl=1ms
E:  Ad=83(I) Atr=03(Int.) MxPS=   4 Ivl=1ms
E:  Ad=04(O) Atr=03(Int.) MxPS=   4 Ivl=1ms
I:* If#= 1 Alt= 0 #EPs= 4 Cls=ff(vend.) Sub=03 Prot=ff Driver=(none)
E:  Ad=81(I) Atr=01(Isoc) MxPS=   4 Ivl=1ms
E:  Ad=02(O) Atr=01(Isoc) MxPS=   4 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=   4 Ivl=1ms
E:  Ad=04(O) Atr=01(Isoc) MxPS=   4 Ivl=1ms

usb 1-2: new full speed USB device using uhci_hcd and address 2
usb 1-2: string descriptor 0 read error: -61
usb 1-2: configuration #1 chosen from 1 choice
------------[ cut here ]------------
WARNING: at fs/sysfs/dir.c:487 sysfs_add_one+0x85/0x99()
sysfs: cannot create duplicate filename '/class/usb_endpoint/usbdev1.2_ep81'
Modules linked in: uhci_hcd usbhid
Pid: 118, comm: khubd Not tainted 2.6.30-rc5 #1
Call Trace:
 [<ffffffff8022e2fa>] ? warn_slowpath_fmt+0xd9/0x10b
 [<ffffffff802f72ae>] ? number+0x122/0x209
 [<ffffffff802f2bf5>] ? idr_get_empty_slot+0x1bf/0x2c2
 [<ffffffff802f2de5>] ? ida_get_new_above+0xed/0x1d2
 [<ffffffff802b8102>] ? sysfs_pathname+0x35/0x3d
 [<ffffffff802b8102>] ? sysfs_pathname+0x35/0x3d
 [<ffffffff802b818f>] ? sysfs_add_one+0x85/0x99
 [<ffffffff802b8688>] ? create_dir+0x4f/0x86
 [<ffffffff802b86f4>] ? sysfs_create_dir+0x35/0x4a
 [<ffffffff802f395d>] ? kobject_get+0x12/0x17
 [<ffffffff802f3a73>] ? kobject_add_internal+0xb6/0x196
 [<ffffffff802f3d00>] ? kobject_add+0x74/0x7c
 [<ffffffff80357489>] ? dev_set_name+0x4d/0x55
 [<ffffffff802f2bf5>] ? idr_get_empty_slot+0x1bf/0x2c2
 [<ffffffff80397378>] ? usb_match_id+0x32/0x58
 [<ffffffff802f395d>] ? kobject_get+0x12/0x17
 [<ffffffff80357953>] ? get_device+0x14/0x1b
 [<ffffffff803580db>] ? device_add+0xe6/0x594
 [<ffffffff802f37da>] ? kobject_init+0x42/0x82
 [<ffffffff8039b0cd>] ? usb_create_ep_devs+0x236/0x2ca
 [<ffffffff803957e3>] ? create_intf_ep_devs+0x41/0x5a
 [<ffffffff80397048>] ? usb_set_configuration+0x52c/0x555
 [<ffffffff8039e1e3>] ? generic_probe+0x55/0x9e
 [<ffffffff8035a035>] ? driver_probe_device+0x8c/0x126
 [<ffffffff8035a13e>] ? __device_attach+0x0/0x39
 [<ffffffff80359737>] ? bus_for_each_drv+0x46/0x77
 [<ffffffff8035a1ec>] ? device_attach+0x52/0x63
 [<ffffffff80359577>] ? bus_attach_device+0x24/0x5b
 [<ffffffff80358447>] ? device_add+0x452/0x594
 [<ffffffff80396b14>] ? usb_cache_string+0x71/0x79
 [<ffffffff8039182d>] ? usb_new_device+0x60/0xbe
 [<ffffffff80392ca4>] ? hub_thread+0xad5/0x1005
 [<ffffffff8023e49b>] ? autoremove_wake_function+0x0/0x2e
 [<ffffffff803921cf>] ? hub_thread+0x0/0x1005
 [<ffffffff803921cf>] ? hub_thread+0x0/0x1005
 [<ffffffff8023e054>] ? kthread+0x4e/0x78
 [<ffffffff8020c78a>] ? child_rip+0xa/0x20
 [<ffffffff80210a78>] ? sched_clock+0x5/0x8
 [<ffffffff8023e006>] ? kthread+0x0/0x78
 [<ffffffff8020c780>] ? child_rip+0x0/0x20
---[ end trace 3c3f00ed226fbe6a ]---
kobject_add_internal failed for usbdev1.2_ep81 with -EEXIST, don't try to register things with the same name in the same directory.
Pid: 118, comm: khubd Tainted: G        W  2.6.30-rc5 #1
Call Trace:
 [<ffffffff802f3b40>] ? kobject_add_internal+0x183/0x196
 [<ffffffff802f3d00>] ? kobject_add+0x74/0x7c
 [<ffffffff80357489>] ? dev_set_name+0x4d/0x55
 [<ffffffff802f2bf5>] ? idr_get_empty_slot+0x1bf/0x2c2
 [<ffffffff80397378>] ? usb_match_id+0x32/0x58
 [<ffffffff802f395d>] ? kobject_get+0x12/0x17
 [<ffffffff80357953>] ? get_device+0x14/0x1b
 [<ffffffff803580db>] ? device_add+0xe6/0x594
 [<ffffffff802f37da>] ? kobject_init+0x42/0x82
 [<ffffffff8039b0cd>] ? usb_create_ep_devs+0x236/0x2ca
 [<ffffffff803957e3>] ? create_intf_ep_devs+0x41/0x5a
 [<ffffffff80397048>] ? usb_set_configuration+0x52c/0x555
 [<ffffffff8039e1e3>] ? generic_probe+0x55/0x9e
 [<ffffffff8035a035>] ? driver_probe_device+0x8c/0x126
 [<ffffffff8035a13e>] ? __device_attach+0x0/0x39
 [<ffffffff80359737>] ? bus_for_each_drv+0x46/0x77
 [<ffffffff8035a1ec>] ? device_attach+0x52/0x63
 [<ffffffff80359577>] ? bus_attach_device+0x24/0x5b
 [<ffffffff80358447>] ? device_add+0x452/0x594
 [<ffffffff80396b14>] ? usb_cache_string+0x71/0x79
 [<ffffffff8039182d>] ? usb_new_device+0x60/0xbe
 [<ffffffff80392ca4>] ? hub_thread+0xad5/0x1005
 [<ffffffff8023e49b>] ? autoremove_wake_function+0x0/0x2e
 [<ffffffff803921cf>] ? hub_thread+0x0/0x1005
 [<ffffffff803921cf>] ? hub_thread+0x0/0x1005
 [<ffffffff8023e054>] ? kthread+0x4e/0x78
 [<ffffffff8020c78a>] ? child_rip+0xa/0x20
 [<ffffffff80210a78>] ? sched_clock+0x5/0x8
 [<ffffffff8023e006>] ? kthread+0x0/0x78
 [<ffffffff8020c780>] ? child_rip+0x0/0x20
------------[ cut here ]------------

-- 
David Fries <david@fries.net>
http://fries.net/~david/ (PGP encryption key available)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bad endpoint address, MOTU FastLane
  2009-05-11 22:12 bad endpoint address, MOTU FastLane David Fries
@ 2009-05-12  7:55 ` Clemens Ladisch
  2009-05-12 14:08   ` Alan Stern
  2009-05-24 22:07   ` David Fries
  0 siblings, 2 replies; 9+ messages in thread
From: Clemens Ladisch @ 2009-05-12  7:55 UTC (permalink / raw)
  To: David Fries; +Cc: David Griffith, Andrew Morton, linux-kernel, linux-usb, todd

David Fries wrote:
> usb_submit_urb returns -22 EINVAL invalid argument as it is trying to
> submit an interrupt packet to what is registered as an isoc endpoint.
> The second interface has the same end point addresses as the first.
> Any suggestions on how to deal with this class of broken hardware?
> 
> I:* If#= 0 Alt= 0 ...
> E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=1ms
> I:* If#= 1 Alt= 0 ...
> E:  Ad=81(I) Atr=01(Isoc) MxPS=   4 Ivl=1ms

AFAICS the USB core memorizes the descriptor belonging to a specific
endpoint number whenever usb_set_interface() is called.  In this case,
the second interface is initialized later, so the second set of
descriptors wins.

The driver could call usb_set_interface() again for the first interface
so that the USB core takes notice of the first set of endpoints again.
Please try the patch below.

I guess I'll have to write another quirk for this.


--- linux/sound/usb/usbmidi.c
+++ linux/sound/usb/usbmidi.c
@@ -1779,6 +1779,7 @@
 		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
 		break;
 	case QUIRK_MIDI_RAW:
+		usb_set_interface(umidi->chip->dev, 0, 0);
 		umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
 		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
 		break;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bad endpoint address, MOTU FastLane
  2009-05-12  7:55 ` Clemens Ladisch
@ 2009-05-12 14:08   ` Alan Stern
  2009-05-12 15:22     ` Todd T. Fries
  2009-05-24 22:07   ` David Fries
  1 sibling, 1 reply; 9+ messages in thread
From: Alan Stern @ 2009-05-12 14:08 UTC (permalink / raw)
  To: Clemens Ladisch
  Cc: David Fries, David Griffith, Andrew Morton, linux-kernel,
	linux-usb, todd

On Tue, 12 May 2009, Clemens Ladisch wrote:

> David Fries wrote:
> > usb_submit_urb returns -22 EINVAL invalid argument as it is trying to
> > submit an interrupt packet to what is registered as an isoc endpoint.

How does one know which type the endpoint really is?  Through prior 
experience with the device?

> > The second interface has the same end point addresses as the first.
> > Any suggestions on how to deal with this class of broken hardware?
> > 
> > I:* If#= 0 Alt= 0 ...
> > E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=1ms
> > I:* If#= 1 Alt= 0 ...
> > E:  Ad=81(I) Atr=01(Isoc) MxPS=   4 Ivl=1ms
> 
> AFAICS the USB core memorizes the descriptor belonging to a specific
> endpoint number whenever usb_set_interface() is called.  In this case,
> the second interface is initialized later, so the second set of
> descriptors wins.
> 
> The driver could call usb_set_interface() again for the first interface
> so that the USB core takes notice of the first set of endpoints again.
> Please try the patch below.
> 
> I guess I'll have to write another quirk for this.
> 
> 
> --- linux/sound/usb/usbmidi.c
> +++ linux/sound/usb/usbmidi.c
> @@ -1779,6 +1779,7 @@
>  		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
>  		break;
>  	case QUIRK_MIDI_RAW:
> +		usb_set_interface(umidi->chip->dev, 0, 0);
>  		umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
>  		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
>  		break;

This is only a bandaid.  The underlying problem is still there.  
Basically, the second interface shouldn't exist at all.  The only
proper way to deal with it is to pretend there's only one interface --
which would mean changing the descriptors before the kernel parses
them.

A much easier approach is to throw the device away and replace it with 
something that _is_ compliant with the USB specification.

Alan Stern


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bad endpoint address, MOTU FastLane
  2009-05-12 14:08   ` Alan Stern
@ 2009-05-12 15:22     ` Todd T. Fries
  2009-05-12 15:44       ` Alan Stern
  0 siblings, 1 reply; 9+ messages in thread
From: Todd T. Fries @ 2009-05-12 15:22 UTC (permalink / raw)
  To: Alan Stern
  Cc: Clemens Ladisch, David Fries, David Griffith, Andrew Morton,
	linux-kernel, linux-usb

I'm actually the owner of said device, and have actually purchased
something that is complaint.  However, not all owners of said device
are as able or willing.

The point in my opinion is that it used to work and now after an upgrade
(to support a pchdtv.com tuner) the MOTU doesn't, only the software has
changed.  Thanks for giving me one more reason to avoid Linux.

IMHO the principal of 'be generous in what you accept, strict in what you give..'
for specs applies here..

Worst case, quirk entry, eh?

Penned by Alan Stern on 20090512 10:08.01, we have:
| On Tue, 12 May 2009, Clemens Ladisch wrote:
| 
| > David Fries wrote:
| > > usb_submit_urb returns -22 EINVAL invalid argument as it is trying to
| > > submit an interrupt packet to what is registered as an isoc endpoint.
| 
| How does one know which type the endpoint really is?  Through prior 
| experience with the device?
| 
| > > The second interface has the same end point addresses as the first.
| > > Any suggestions on how to deal with this class of broken hardware?
| > > 
| > > I:* If#= 0 Alt= 0 ...
| > > E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=1ms
| > > I:* If#= 1 Alt= 0 ...
| > > E:  Ad=81(I) Atr=01(Isoc) MxPS=   4 Ivl=1ms
| > 
| > AFAICS the USB core memorizes the descriptor belonging to a specific
| > endpoint number whenever usb_set_interface() is called.  In this case,
| > the second interface is initialized later, so the second set of
| > descriptors wins.
| > 
| > The driver could call usb_set_interface() again for the first interface
| > so that the USB core takes notice of the first set of endpoints again.
| > Please try the patch below.
| > 
| > I guess I'll have to write another quirk for this.
| > 
| > 
| > --- linux/sound/usb/usbmidi.c
| > +++ linux/sound/usb/usbmidi.c
| > @@ -1779,6 +1779,7 @@
| >  		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
| >  		break;
| >  	case QUIRK_MIDI_RAW:
| > +		usb_set_interface(umidi->chip->dev, 0, 0);
| >  		umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
| >  		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
| >  		break;
| 
| This is only a bandaid.  The underlying problem is still there.  
| Basically, the second interface shouldn't exist at all.  The only
| proper way to deal with it is to pretend there's only one interface --
| which would mean changing the descriptors before the kernel parses
| them.
| 
| A much easier approach is to throw the device away and replace it with 
| something that _is_ compliant with the USB specification.
| 
| Alan Stern

-- 
Todd Fries .. todd@fries.net

 _____________________________________________
|                                             \  1.636.410.0632 (voice)
| Free Daemon Consulting, LLC                 \  1.405.227.9094 (voice)
| http://FreeDaemonConsulting.com             \  1.866.792.3418 (FAX)
| "..in support of free software solutions."  \          250797 (FWD)
|                                             \
 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
                                                 
              37E7 D3EB 74D0 8D66 A68D  B866 0326 204E 3F42 004A
                        http://todd.fries.net/pgp.txt


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bad endpoint address, MOTU FastLane
  2009-05-12 15:22     ` Todd T. Fries
@ 2009-05-12 15:44       ` Alan Stern
  0 siblings, 0 replies; 9+ messages in thread
From: Alan Stern @ 2009-05-12 15:44 UTC (permalink / raw)
  To: Todd T. Fries
  Cc: Clemens Ladisch, David Fries, David Griffith, Andrew Morton,
	linux-kernel, linux-usb

On Tue, 12 May 2009, Todd T. Fries wrote:

> I'm actually the owner of said device, and have actually purchased
> something that is complaint.  However, not all owners of said device
> are as able or willing.
> 
> The point in my opinion is that it used to work and now after an upgrade
> (to support a pchdtv.com tuner) the MOTU doesn't, only the software has
> changed.  Thanks for giving me one more reason to avoid Linux.

The fact that it worked before was, as I said, a mere coincidence.  You 
don't seem to appreciate just how badly out-of-spec this device is.

> IMHO the principal of 'be generous in what you accept, strict in what you give..'
> for specs applies here..

That pinciple doesn't help much if what you're trying to accept is 
self-contradictory, as it is in this case.

> Worst case, quirk entry, eh?

If the quirk entry helps, feel free to use it.  And don't be surprised 
if future software upgrades cause similar problems.

Alan Stern


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bad endpoint address, MOTU FastLane
  2009-05-12  7:55 ` Clemens Ladisch
  2009-05-12 14:08   ` Alan Stern
@ 2009-05-24 22:07   ` David Fries
  2009-05-25  8:20     ` Clemens Ladisch
  1 sibling, 1 reply; 9+ messages in thread
From: David Fries @ 2009-05-24 22:07 UTC (permalink / raw)
  To: Clemens Ladisch
  Cc: David Griffith, Andrew Morton, Alan Stern, linux-kernel,
	linux-usb

On Tue, May 12, 2009 at 09:55:08AM +0200, Clemens Ladisch wrote:
> David Fries wrote:
> > usb_submit_urb returns -22 EINVAL invalid argument as it is trying to
> > submit an interrupt packet to what is registered as an isoc endpoint.
> > The second interface has the same end point addresses as the first.
> > Any suggestions on how to deal with this class of broken hardware?
> > 
> > I:* If#= 0 Alt= 0 ...
> > E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=1ms
> > I:* If#= 1 Alt= 0 ...
> > E:  Ad=81(I) Atr=01(Isoc) MxPS=   4 Ivl=1ms
> 
> AFAICS the USB core memorizes the descriptor belonging to a specific
> endpoint number whenever usb_set_interface() is called.  In this case,
> the second interface is initialized later, so the second set of
> descriptors wins.
> 
> The driver could call usb_set_interface() again for the first interface
> so that the USB core takes notice of the first set of endpoints again.
> Please try the patch below.
> 
> I guess I'll have to write another quirk for this.

Thanks for the quick response, sorry for taking so long to test it.
Adding usb_set_interface lets the device work again, I had been
tracking this down for a while, I'm glad you knew what to do.

The MOTU Fastlane device is the only one using QUIRK_MIDI_RAW.  How about
changing the name to QUIRK_MIDI_FASTLANE to imply it isn't completely
generic anymore and adding a comment?  I can write up that patch if
it's agreeable.  The only danger I see is if there are some MOTU
Fastlane devices with a corrected descriptor record, but if that were
the case setting it to the 0 alternative setting would be a no-op in
that case, so it sounds good to me.

	case QUIRK_MIDI_FASTLANE:
		/* MOTU Fastlane has two interfaces with the second
		 * interface reusing the endpoint addresses voilating
		 * the standard.  Select interface 0 again to reload
		 * that configuration.
		 */
		usb_set_interface(umidi->chip->dev, 0, 0);
		umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
		break;

> --- linux/sound/usb/usbmidi.c
> +++ linux/sound/usb/usbmidi.c
> @@ -1779,6 +1779,7 @@
>  		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
>  		break;
>  	case QUIRK_MIDI_RAW:
> +		usb_set_interface(umidi->chip->dev, 0, 0);
>  		umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
>  		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
>  		break;
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
David Fries <david@fries.net>
http://fries.net/~david/ (PGP encryption key available)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bad endpoint address, MOTU FastLane
  2009-05-24 22:07   ` David Fries
@ 2009-05-25  8:20     ` Clemens Ladisch
  2009-05-26  0:41       ` David Fries
  0 siblings, 1 reply; 9+ messages in thread
From: Clemens Ladisch @ 2009-05-25  8:20 UTC (permalink / raw)
  To: David Fries
  Cc: David Griffith, Andrew Morton, Alan Stern, linux-kernel,
	linux-usb

David Fries wrote:
> On Tue, May 12, 2009 at 09:55:08AM +0200, Clemens Ladisch wrote:
> > The driver could call usb_set_interface() again for the first interface
> > so that the USB core takes notice of the first set of endpoints again.
> > Please try the patch below.
> > 
> > I guess I'll have to write another quirk for this.
> 
> Adding usb_set_interface lets the device work again, ...
> 
> The MOTU Fastlane device is the only one using QUIRK_MIDI_RAW.  How about
> changing the name to QUIRK_MIDI_FASTLANE to imply it isn't completely
> generic anymore and adding a comment?

And while we're at it, the driver should claim interface 1 to prevent
anyone else from using it.

New patch below.

Are you okay with the tested-by tag?

===========

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>

--- linux/sound/usb/usbaudio.h
+++ linux/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,
--- linux/sound/usb/usbquirks.h
+++ linux/sound/usb/usbquirks.h
@@ -1868,11 +1868,11 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 		.data = & (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
-				.type = QUIRK_MIDI_RAW
+				.type = QUIRK_MIDI_FASTLANE
 			},
 			{
 				.ifnum = 1,
-				.type = QUIRK_IGNORE_INTERFACE
+				.type = QUIRK_MIDI_FASTLANE
 			},
 			{
 				.ifnum = -1
--- linux/sound/usb/usbaudio.c
+++ linux/sound/usb/usbaudio.c
@@ -3359,7 +3359,7 @@ static int snd_usb_create_quirk(struct s
 		[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,

--- linux/sound/usb/usbmidi.c
+++ linux/sound/usb/usbmidi.c
@@ -1573,6 +1573,33 @@ static int snd_usbmidi_detect_yamaha(str
 }
 
 /*
+ * Detects the endpoints and ports of the MotU Fastlane, and handles the
+ * interfaces' configuration.
+ */
+static int snd_usbmidi_detect_fastlane(struct snd_usb_midi *umidi,
+				       struct snd_usb_midi_endpoint_info *eps)
+{
+	switch (get_iface_desc(umidi->iface->altsetting)->bInterfaceNumber) {
+	case 0:
+		/*
+		 * 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);
+		return snd_usbmidi_detect_per_port_endpoints(umidi, eps);
+	case 1:
+		return 1; /* no MIDI device for this interface, just claim it */
+	default:
+		return -ENXIO;
+	}
+}
+
+/*
  * Creates the endpoints and their ports for Midiman devices.
  */
 static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi,
@@ -1778,9 +1805,13 @@ int snd_usb_create_midi_interface(struct
 		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;
-		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+		err = snd_usbmidi_detect_fastlane(umidi, endpoints);
+		if (err == 1) {
+			kfree(umidi);
+			return 0;
+		}
 		break;
 	case QUIRK_MIDI_EMAGIC:
 		umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bad endpoint address, MOTU FastLane
  2009-05-25  8:20     ` Clemens Ladisch
@ 2009-05-26  0:41       ` David Fries
  2009-05-26  7:25         ` Clemens Ladisch
  0 siblings, 1 reply; 9+ messages in thread
From: David Fries @ 2009-05-26  0:41 UTC (permalink / raw)
  To: Clemens Ladisch
  Cc: David Griffith, Andrew Morton, Alan Stern, linux-kernel,
	linux-usb

On Mon, May 25, 2009 at 10:20:43AM +0200, Clemens Ladisch wrote:
> David Fries wrote:
> > On Tue, May 12, 2009 at 09:55:08AM +0200, Clemens Ladisch wrote:
> > > The driver could call usb_set_interface() again for the first interface
> > > so that the USB core takes notice of the first set of endpoints again.
> > > Please try the patch below.
> > > 
> > > I guess I'll have to write another quirk for this.
> > 
> > Adding usb_set_interface lets the device work again, ...
> > 
> > The MOTU Fastlane device is the only one using QUIRK_MIDI_RAW.  How about
> > changing the name to QUIRK_MIDI_FASTLANE to imply it isn't completely
> > generic anymore and adding a comment?
> 
> And while we're at it, the driver should claim interface 1 to prevent
> anyone else from using it.

Before and after the latest patch snd-usb-audio claims interface 1.
I:* If#= 0 Alt= 0 #EPs= 4 Cls=ff(vend.) Sub=04 Prot=ff Driver=snd-usb-audio
I:* If#= 1 Alt= 0 #EPs= 4 Cls=ff(vend.) Sub=03 Prot=ff Driver=snd-usb-audio

The new snd_usbmidi_detect_fastlane in case 1 returns 1, which then
will return 0 from snd_usb_create_midi_interface, but
ignore_interface_quirk already returns 0 if it was left with the
ignore interface quirk, so I don't see a need for that part of the
patch.

> New patch below.
> 
> Are you okay with the tested-by tag?

Yes, it works.  I'm watching the LEDs blink on the device and data
come across.

> +static int snd_usbmidi_detect_fastlane(struct snd_usb_midi *umidi,
> +				       struct snd_usb_midi_endpoint_info *eps)
> +{
> +	switch (get_iface_desc(umidi->iface->altsetting)->bInterfaceNumber) {
...
> +	case 1:
> +		return 1; /* no MIDI device for this interface, just claim it */

> @@ -1778,9 +1805,13 @@ int snd_usb_create_midi_interface(struct
> +		err = snd_usbmidi_detect_fastlane(umidi, endpoints);
> +		if (err == 1) {
> +			kfree(umidi);
> +			return 0;
> +		}

-- 
David Fries <david@fries.net>
http://fries.net/~david/ (PGP encryption key available)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: bad endpoint address, MOTU FastLane
  2009-05-26  0:41       ` David Fries
@ 2009-05-26  7:25         ` Clemens Ladisch
  0 siblings, 0 replies; 9+ messages in thread
From: Clemens Ladisch @ 2009-05-26  7:25 UTC (permalink / raw)
  To: David Fries
  Cc: David Griffith, Andrew Morton, Alan Stern, linux-kernel,
	linux-usb

David Fries wrote:
> On Mon, May 25, 2009 at 10:20:43AM +0200, Clemens Ladisch wrote:
> > David Fries wrote:
> > > The MOTU Fastlane device is the only one using QUIRK_MIDI_RAW.  How about
> > > changing the name to QUIRK_MIDI_FASTLANE to imply it isn't completely
> > > generic anymore and adding a comment?
> > 
> > And while we're at it, the driver should claim interface 1 to prevent
> > anyone else from using it.
> 
> Before and after the latest patch snd-usb-audio claims interface 1.

Oops.  Well, that makes the patch easier.  ;-)

> > New patch below.
> > 
> > Are you okay with the tested-by tag?
> 
> Yes, it works.  I'm watching the LEDs blink on the device and data
> come across.

Okay, I'll applay it in the sound tree.


Best regards,
Clemens

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2009-05-26  7:26 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-11 22:12 bad endpoint address, MOTU FastLane David Fries
2009-05-12  7:55 ` Clemens Ladisch
2009-05-12 14:08   ` Alan Stern
2009-05-12 15:22     ` Todd T. Fries
2009-05-12 15:44       ` Alan Stern
2009-05-24 22:07   ` David Fries
2009-05-25  8:20     ` Clemens Ladisch
2009-05-26  0:41       ` David Fries
2009-05-26  7:25         ` Clemens Ladisch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox