2013-03-11 03:52:12

by Dave Helstroom

[permalink] [raw]
Subject: [PATCH][RESEND] Add a USB audio quirk for the NuForce UDH-100 device.

From: Dave Helstroom <[email protected]>

Interface 1 does not exist and Interface 0 should be ignored. Before this
patch, the device would not show up in /dev/snd (and dmesg showed Error -5
from the snd-alsa-usb module); after this patch, the device shows up
correctly in /dev/snd and ALSA/Pulseaudio can access it.


Signed-off-by: Dave Helstroom <[email protected]>
---
sound/usb/quirks-table.h | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)

diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index c39f898..62d29ca 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2795,6 +2795,38 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},

+/* NuForce devices */
+{
+ USB_DEVICE(0x16d0, 0x0631),
+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+ .vendor_name = "Nuforce",
+ .product_name = "UDH-100",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = (const struct snd_usb_audio_quirk[]) {
+ {
+ .ifnum = 0,
+ .type = QUIRK_IGNORE_INTERFACE
+ },
+ {
+ .ifnum = 1,
+ .type = QUIRK_IGNORE_INTERFACE
+ },
+ {
+ .ifnum = 2,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 3,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = -1
+ }
+ }
+ }
+},
+
/* Native Instruments MK2 series */
{
/* Komplete Audio 6 */
--
1.8.1.3


2013-03-11 08:32:15

by Clemens Ladisch

[permalink] [raw]
Subject: Re: [PATCH][RESEND] Add a USB audio quirk for the NuForce UDH-100 device.

David Helstroom wrote:
> Interface 1 does not exist

Then it doesn't need a quirk, does it?

> and Interface 0 should be ignored.

Why?

If the driver doesn't like something in interface 0, that bug should be
fixed.

What is the output of "lsusb -v" for this device?


Regards,
Clemens

2013-03-11 18:03:43

by Dave Helstroom

[permalink] [raw]
Subject: Re: [PATCH][RESEND] Add a USB audio quirk for the NuForce UDH-100 device.

On 11 March 2013 01:32, Clemens Ladisch <[email protected]> wrote:
> David Helstroom wrote:
>> Interface 1 does not exist
>
> Then it doesn't need a quirk, does it?

Perhaps that's the case. I just know that without
QUIRK_IGNORE_INTERFACE for ifnum 1, the kernel refuses to properly
configure the output device. From dmesg without this patch:
[ 3254.192225] usb 1-1: new high-speed USB device number 6 using ehci_hcd
[ 3254.343554] usb 1-1: config 1 has an invalid interface number: 3 but max is 2
[ 3254.343558] usb 1-1: config 1 has an invalid interface number: 3 but max is 2
[ 3254.343562] usb 1-1: config 1 has an invalid interface number: 3 but max is 2
[ 3254.343565] usb 1-1: config 1 has an invalid interface number: 3 but max is 2
[ 3254.343568] usb 1-1: config 1 has no interface number 1
[ 3254.345988] input: Nuforce Inc., Nuforce 192k USB DAC as
/devices/pci0000:00/0000:00:1a.7/usb1/1-1/1-1:1.0/input/input10
[ 3254.346202] generic-usb 0003:16D0:0631.0007: input,hidraw0: USB HID
v1.00 Device [Nuforce Inc., Nuforce 192k USB DAC] on
usb-0000:00:1a.7-1/input0
[ 3254.355970] Audio class v2 interfaces need an interface association
[ 3254.355988] snd-usb-audio: probe of 1-1:1.2 failed with error -5
[ 3254.356045] usbcore: registered new interface driver snd-usb-audio

>> and Interface 0 should be ignored.
>
> Why?
>
> If the driver doesn't like something in interface 0, that bug should be
> fixed.
>
> What is the output of "lsusb -v" for this device?

I've put up the relevant output on: http://pastebin.com/i4wpQ35B
Note that I'm testing on an older kernel here (3.2.5), so perhaps a
more fundamental fix has already made its way into the USB audio
stack. I'll arrange to test on a more recent kernel too.

2013-03-11 19:16:50

by Clemens Ladisch

[permalink] [raw]
Subject: Re: [PATCH][RESEND] Add a USB audio quirk for the NuForce UDH-100 device.

>> David Helstroom wrote:
>>> Interface 1 does not exist

Please try the patch below.


Regards,
Clemens


--8<---------------------------------------------------------------->8--
ALSA: usb-audio: add a workaround for the NuForce UDH-100

The NuForce UDH-100 numbers its interfaces incorrectly, which makes the
interface associations come out wrong, which results in the driver
erroring out with the message "Audio class v2 interfaces need an
interface association".

Work around this by searching for the interface association descriptor
also in some other place where it might have ended up.

Reported-by: Dave Helstroom <[email protected]>
Signed-off-by: Clemens Ladisch <[email protected]>
---
sound/usb/card.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index df2f6d0..34dc3e8 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -245,6 +245,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
usb_ifnum_to_if(dev, ctrlif)->intf_assoc;

if (!assoc) {
+ /*
+ * Firmware writers cannot count to three. So to find
+ * the IAD on the NuForce UDH-100, also check the next
+ * interface.
+ */
+ struct usb_interface *iface =
+ usb_ifnum_to_if(dev, ctrlif + 1);
+ if (iface &&
+ iface->intf_assoc &&
+ iface->intf_assoc->bFunctionClass == USB_CLASS_AUDIO &&
+ iface->intf_assoc->bFunctionProtocol == UAC_VERSION_2)
+ assoc = iface->intf_assoc;
+ }
+
+ if (!assoc) {
snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
return -EINVAL;
}

2013-03-11 23:58:54

by Dave Helstroom

[permalink] [raw]
Subject: Re: [PATCH][RESEND] Add a USB audio quirk for the NuForce UDH-100 device.

On 11 March 2013 12:15, Clemens Ladisch <[email protected]> wrote:
>
> >> David Helstroom wrote:
> >>> Interface 1 does not exist
>
> Please try the patch below.

This works great for me -- thanks a lot!

My only suggestion (from a kernel newbie so feel free to ignore),
would be that it might be worthwhile even walking the entire set of
ifaces in case some other firmware decides to put the IAD even further
down the interface list. However you're obviously much better placed
as to the likelihood/worth of that occurring. Thanks again!

2013-03-12 07:36:32

by Takashi Iwai

[permalink] [raw]
Subject: Re: [PATCH][RESEND] Add a USB audio quirk for the NuForce UDH-100 device.

At Mon, 11 Mar 2013 20:15:34 +0100,
Clemens Ladisch wrote:
>
> >> David Helstroom wrote:
> >>> Interface 1 does not exist
>
> Please try the patch below.

Since the patch seems working, I merge it now.


thanks,

Takashi

>
>
> Regards,
> Clemens
>
>
> --8<---------------------------------------------------------------->8--
> ALSA: usb-audio: add a workaround for the NuForce UDH-100
>
> The NuForce UDH-100 numbers its interfaces incorrectly, which makes the
> interface associations come out wrong, which results in the driver
> erroring out with the message "Audio class v2 interfaces need an
> interface association".
>
> Work around this by searching for the interface association descriptor
> also in some other place where it might have ended up.
>
> Reported-by: Dave Helstroom <[email protected]>
> Signed-off-by: Clemens Ladisch <[email protected]>
> ---
> sound/usb/card.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/sound/usb/card.c b/sound/usb/card.c
> index df2f6d0..34dc3e8 100644
> --- a/sound/usb/card.c
> +++ b/sound/usb/card.c
> @@ -245,6 +245,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
> usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
>
> if (!assoc) {
> + /*
> + * Firmware writers cannot count to three. So to find
> + * the IAD on the NuForce UDH-100, also check the next
> + * interface.
> + */
> + struct usb_interface *iface =
> + usb_ifnum_to_if(dev, ctrlif + 1);
> + if (iface &&
> + iface->intf_assoc &&
> + iface->intf_assoc->bFunctionClass == USB_CLASS_AUDIO &&
> + iface->intf_assoc->bFunctionProtocol == UAC_VERSION_2)
> + assoc = iface->intf_assoc;
> + }
> +
> + if (!assoc) {
> snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
> return -EINVAL;
> }
>