From e6f7d9cb3c92b49d70da0afe74d0d31df715df6f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 8 Jun 2012 09:01:37 +0200 Subject: [PATCH] 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-g71fae7e #2 Call Trace: [] warn_slowpath_common+0x83/0x9c [] warn_slowpath_fmt+0x46/0x48 [] ? add_preempt_count+0x39/0x3b [] proc_register+0x169/0x1a6 [] create_proc_entry+0x74/0x8c [] snd_info_register+0x3e/0xc3 [snd] [] snd_pcm_new_stream+0xb1/0x404 [snd_pcm] [] snd_usb_add_audio_stream+0xd2/0x230 [snd_usb_audio] [] ? snd_usb_parse_audio_format+0x252/0x34f [snd_usb_audio] [] ? kmem_cache_alloc_trace+0xab/0xbb [] snd_usb_parse_audio_interface+0x4ac/0x567 [snd_usb_audio] [] snd_usb_create_stream+0xe9/0x125 [snd_usb_audio] [] 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: Jamie Heilman Signed-off-by: Takashi Iwai --- sound/usb/card.h | 1 + sound/usb/stream.c | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/usb/card.h b/sound/usb/card.h index 0d37238b84572..2b9fffff23b62 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -119,6 +119,7 @@ struct snd_usb_substream { unsigned long unlink_mask; /* bitmask of unlinked urbs */ /* data and sync endpoints for this stream */ + unsigned int ep_num; /* the endpoint number */ struct snd_usb_endpoint *data_endpoint; struct snd_usb_endpoint *sync_endpoint; unsigned long flags; diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 6b7d7a2b7baa3..083ed81160e58 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -97,6 +97,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as, subs->formats |= fp->formats; subs->num_formats++; 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, if (as->fmt_type != fp->fmt_type) continue; subs = &as->substream[stream]; - if (!subs->data_endpoint) - continue; - if (subs->data_endpoint->ep_num == fp->endpoint) { + if (subs->ep_num == fp->endpoint) { list_add_tail(&fp->list, &subs->fmt_list); subs->num_formats++; subs->formats |= fp->formats; @@ -134,7 +133,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, if (as->fmt_type != fp->fmt_type) continue; subs = &as->substream[stream]; - if (subs->data_endpoint) + if (subs->ep_num) continue; err = snd_pcm_new_stream(as->pcm, stream, 1); if (err < 0) -- 2.39.5