diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2015-02-21 17:54:59 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-02-23 11:11:16 +0300 |
commit | d23c2cc4485d10f0cedfef99dd2961d9652b1b3f (patch) | |
tree | 27c558371d511e9f93ef12c4d656fbb409fc087c /sound/firewire/fireworks | |
parent | c6f224dc20ad959175c2dfec70b5a61c6503a793 (diff) | |
download | linux-d23c2cc4485d10f0cedfef99dd2961d9652b1b3f.tar.xz |
ALSA: fireworks/bebob/dice/oxfw: allow stream destructor after releasing runtime
Currently stream destructor in each driver has a problem to be called in
a context in which sound card object is released, because the destructors
call amdtp_stream_pcm_abort() and touch PCM runtime data.
The PCM runtime data is destroyed in application's context with
snd_pcm_close(), on the other hand PCM substream data is destroyed after
sound card object is released, in most case after all of ALSA character
devices are released. When PCM runtime is destroyed and PCM substream is
remained, amdtp_stream_pcm_abort() touches PCM runtime data and causes
Null-pointer-dereference.
This commit changes stream destructors and allows each driver to call
it after releasing runtime.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Cc: <stable@vger.kernel.org> # 3.19+
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/fireworks')
-rw-r--r-- | sound/firewire/fireworks/fireworks_stream.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index 4f440e163667..f817b7ae097e 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c @@ -100,17 +100,22 @@ end: return err; } +/* + * This function should be called before starting the stream or after stopping + * the streams. + */ static void destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream) { - stop_stream(efw, stream); - - amdtp_stream_destroy(stream); + struct cmp_connection *conn; if (stream == &efw->tx_stream) - cmp_connection_destroy(&efw->out_conn); + conn = &efw->out_conn; else - cmp_connection_destroy(&efw->in_conn); + conn = &efw->in_conn; + + amdtp_stream_destroy(stream); + cmp_connection_destroy(&efw->out_conn); } static int |