Commit 8260ef07 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: usb-audio: Fix substream assignments

In 3.5 kernel, the endpoint is assigned dynamically for the
substreams, but the PCM assignment still checks the presence of the
endpoint pointer.  This ended up in duplicated PCM substream creations
at probing time, resulting in kernel warnings like:

WARNING: at fs/proc/generic.c:586 proc_register+0x169/0x1a6()
Pid: 1152, comm: modprobe Not tainted 3.5.0-rc1-00110-g71fae7e7 #2
Call Trace:
 [<ffffffff8102a400>] warn_slowpath_common+0x83/0x9c
 [<ffffffff8102a4bc>] warn_slowpath_fmt+0x46/0x48
 [<ffffffff813829ad>] ? add_preempt_count+0x39/0x3b
 [<ffffffff811292f0>] proc_register+0x169/0x1a6
 [<ffffffff8112962e>] create_proc_entry+0x74/0x8c
 [<ffffffffa018eb63>] snd_info_register+0x3e/0xc3 [snd]
 [<ffffffffa01fde2e>] snd_pcm_new_stream+0xb1/0x404 [snd_pcm]
 [<ffffffffa024861f>] snd_usb_add_audio_stream+0xd2/0x230 [snd_usb_audio]
 [<ffffffffa0241d33>] ? snd_usb_parse_audio_format+0x252/0x34f [snd_usb_audio]
 [<ffffffff810d6b17>] ? kmem_cache_alloc_trace+0xab/0xbb
 [<ffffffffa0248c29>] snd_usb_parse_audio_interface+0x4ac/0x567 [snd_usb_audio]
 [<ffffffffa023f0ff>] snd_usb_create_stream+0xe9/0x125 [snd_usb_audio]
 [<ffffffffa023f9b1>] usb_audio_probe+0x62a/0x72c [snd_usb_audio]
 .....

This patch fixes the regression by checking the fixed endpoint number
for each substream instead of the endpoint pointer.
Reported-and-tested-by: default avatarJamie Heilman <jamie@audible.transient.net>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 69c5b753
...@@ -119,6 +119,7 @@ struct snd_usb_substream { ...@@ -119,6 +119,7 @@ struct snd_usb_substream {
unsigned long unlink_mask; /* bitmask of unlinked urbs */ unsigned long unlink_mask; /* bitmask of unlinked urbs */
/* data and sync endpoints for this stream */ /* data and sync endpoints for this stream */
unsigned int ep_num; /* the endpoint number */
struct snd_usb_endpoint *data_endpoint; struct snd_usb_endpoint *data_endpoint;
struct snd_usb_endpoint *sync_endpoint; struct snd_usb_endpoint *sync_endpoint;
unsigned long flags; unsigned long flags;
......
...@@ -97,6 +97,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as, ...@@ -97,6 +97,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
subs->formats |= fp->formats; subs->formats |= fp->formats;
subs->num_formats++; subs->num_formats++;
subs->fmt_type = fp->fmt_type; subs->fmt_type = fp->fmt_type;
subs->ep_num = fp->endpoint;
} }
/* /*
...@@ -119,9 +120,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, ...@@ -119,9 +120,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
if (as->fmt_type != fp->fmt_type) if (as->fmt_type != fp->fmt_type)
continue; continue;
subs = &as->substream[stream]; subs = &as->substream[stream];
if (!subs->data_endpoint) if (subs->ep_num == fp->endpoint) {
continue;
if (subs->data_endpoint->ep_num == fp->endpoint) {
list_add_tail(&fp->list, &subs->fmt_list); list_add_tail(&fp->list, &subs->fmt_list);
subs->num_formats++; subs->num_formats++;
subs->formats |= fp->formats; subs->formats |= fp->formats;
...@@ -134,7 +133,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, ...@@ -134,7 +133,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
if (as->fmt_type != fp->fmt_type) if (as->fmt_type != fp->fmt_type)
continue; continue;
subs = &as->substream[stream]; subs = &as->substream[stream];
if (subs->data_endpoint) if (subs->ep_num)
continue; continue;
err = snd_pcm_new_stream(as->pcm, stream, 1); err = snd_pcm_new_stream(as->pcm, stream, 1);
if (err < 0) if (err < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment