aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-08-15 12:32:00 +0200
committerTakashi Iwai <tiwai@suse.de>2012-08-16 08:04:07 +0200
commite9ba389c5ffc4dd29dfe17e00e48877302111135 (patch)
treea103bde320260cd42172a9171af0d3fe7da889c4
parent3bdcff70b6cd049e6f4437b955850f5db83653cc (diff)
downloadkernel_goldelico_gta04-e9ba389c5ffc4dd29dfe17e00e48877302111135.zip
kernel_goldelico_gta04-e9ba389c5ffc4dd29dfe17e00e48877302111135.tar.gz
kernel_goldelico_gta04-e9ba389c5ffc4dd29dfe17e00e48877302111135.tar.bz2
ALSA: usb-audio: Fix scheduling-while-atomic bug in PCM capture stream
A PCM capture stream on usb-audio causes a scheduling-while-atomic BUG, as reported in the bugzilla entry below. It's because snd_usb_endpoint_start() is called at first at trigger START for a capture stream, and this function contains the left-over EP deactivation codes. The problem doesn't happen for a playback stream because the function is called at PCM prepare time, which can sleep. This patch fixes the BUG by moving the EP deactivation code into the PCM prepare callback. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=46011 Cc: <stable@vger.kernel.org> [v3.5+] Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/usb/endpoint.c4
-rw-r--r--sound/usb/pcm.c3
2 files changed, 3 insertions, 4 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 0f647d2..c411812 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -821,10 +821,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
if (++ep->use_count != 1)
return 0;
- /* just to be sure */
- deactivate_urbs(ep, 0, 1);
- wait_clear_urbs(ep);
-
ep->active_mask = 0;
ep->unlink_mask = 0;
ep->phase = 0;
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index a1298f3..62ec808 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -544,6 +544,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
subs->last_frame_number = 0;
runtime->delay = 0;
+ /* clear the pending deactivation on the target EPs */
+ deactivate_endpoints(subs);
+
/* for playback, submit the URBs now; otherwise, the first hwptr_done
* updates for all URBs would happen at the same time when starting */
if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)