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>
This commit is contained in:

committed by
Takashi Iwai

父節點
c6f224dc20
當前提交
d23c2cc448
@@ -311,14 +311,21 @@ end:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function should be called before starting streams or after stopping
|
||||
* streams.
|
||||
*/
|
||||
static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream)
|
||||
{
|
||||
amdtp_stream_destroy(stream);
|
||||
struct fw_iso_resources *resources;
|
||||
|
||||
if (stream == &dice->tx_stream)
|
||||
fw_iso_resources_destroy(&dice->tx_resources);
|
||||
resources = &dice->tx_resources;
|
||||
else
|
||||
fw_iso_resources_destroy(&dice->rx_resources);
|
||||
resources = &dice->rx_resources;
|
||||
|
||||
amdtp_stream_destroy(stream);
|
||||
fw_iso_resources_destroy(resources);
|
||||
}
|
||||
|
||||
int snd_dice_stream_init_duplex(struct snd_dice *dice)
|
||||
@@ -332,6 +339,8 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice)
|
||||
goto end;
|
||||
|
||||
err = init_stream(dice, &dice->rx_stream);
|
||||
if (err < 0)
|
||||
destroy_stream(dice, &dice->tx_stream);
|
||||
end:
|
||||
return err;
|
||||
}
|
||||
@@ -340,10 +349,7 @@ void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
|
||||
{
|
||||
snd_dice_transaction_clear_enable(dice);
|
||||
|
||||
stop_stream(dice, &dice->tx_stream);
|
||||
destroy_stream(dice, &dice->tx_stream);
|
||||
|
||||
stop_stream(dice, &dice->rx_stream);
|
||||
destroy_stream(dice, &dice->rx_stream);
|
||||
|
||||
dice->substreams_counter = 0;
|
||||
|
Reference in New Issue
Block a user