From f58161ba1b05a968e5136824b5a16b714b6a5317 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 8 Nov 2012 08:52:45 +0100 Subject: ALSA: usb-audio: Fix crash at re-preparing the PCM stream There are bug reports of a crash with USB-audio devices when PCM prepare is performed immediately after the stream is stopped via trigger callback. It turned out that the problem is that we don't wait until all URBs are killed. This patch adds a new function to synchronize the pending stop operation on an endpoint, and calls in the prepare callback for avoiding the crash above. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=49181 Reported-and-tested-by: Artem S. Tashkinov Cc: [v3.6] Signed-off-by: Takashi Iwai --- sound/usb/endpoint.h | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/usb/endpoint.h') diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 6376ccf10fd4..3d4c9705041f 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h @@ -19,6 +19,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep); void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, int force, int can_sleep, int wait); +void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); void snd_usb_endpoint_free(struct list_head *head); -- cgit v1.2.3 From a9bb36261ef5c7e25564d5ce8a5129920a29bff9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 20 Nov 2012 18:32:06 +0100 Subject: ALSA: usb-audio: simplify snd_usb_endpoint_start/stop arguments Reduce the redundant arguments for snd_usb_endpoint_start() and snd_usb_endpoint_stop(). Also replaced from int to bool. No functional changes by this commit. Signed-off-by: Takashi Iwai --- sound/usb/endpoint.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sound/usb/endpoint.h') diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 3d4c9705041f..f1e451da9a67 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h @@ -16,9 +16,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, struct audioformat *fmt, struct snd_usb_endpoint *sync_ep); -int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep); -void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, - int force, int can_sleep, int wait); +int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep); +void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, bool wait); void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); -- cgit v1.2.3 From b2eb950de2f09435d5156f4dc6d5dbf284cd97f3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 21 Nov 2012 08:30:48 +0100 Subject: ALSA: usb-audio: stop both data and sync endpoints asynchronously As we are stopping the endpoints asynchronously now, it's better to trigger the stop of both data and sync endpoints and wait for pending stopping operations, instead of the sequential trigger-and-wait procedure. So the wait argument in snd_usb_endpoint_stop() is dropped, and it's expected that the caller synchronizes explicitly by calling snd_usb_endpoint_sync_pending_stop(). (Actually there is only one place calling this, so it was safe to change.) Signed-off-by: Takashi Iwai --- sound/usb/endpoint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/usb/endpoint.h') diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index f1e451da9a67..447902dd8a4a 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h @@ -17,7 +17,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, struct snd_usb_endpoint *sync_ep); int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep); -void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, bool wait); +void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep); void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); -- cgit v1.2.3