aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2015-02-21 23:55:00 +0900
committerTakashi Iwai <tiwai@suse.de>2015-02-23 09:11:24 +0100
commitdec84316dd53c90e93b4ee849483bd4bd1e9a585 (patch)
tree3725938633e83ba9bf303e171323bbb911a0ba9f
parentd23c2cc4485d10f0cedfef99dd2961d9652b1b3f (diff)
downloadstm32-dec84316dd53c90e93b4ee849483bd4bd1e9a585.tar.gz
ALSA: fireworks/bebob/dice/oxfw: make it possible to shutdown safely
A part of these drivers, especially BeBoB driver, are programmed to wait some events. Thus the drivers should not destroy any data in .remove() context. This commit moves some destructors from 'struct fw_driver.remove()' to 'struct snd_card.private_free()' to shutdown safely. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Cc: <stable@vger.kernel.org> # 3.19+ Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/firewire/bebob/bebob.c10
-rw-r--r--sound/firewire/bebob/bebob_stream.c4
-rw-r--r--sound/firewire/dice/dice.c5
-rw-r--r--sound/firewire/fireworks/fireworks.c10
-rw-r--r--sound/firewire/fireworks/fireworks_stream.c4
-rw-r--r--sound/firewire/oxfw/oxfw.c10
6 files changed, 15 insertions, 28 deletions
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c
index b612599fb543ea..611b7dae7ee54c 100644
--- a/sound/firewire/bebob/bebob.c
+++ b/sound/firewire/bebob/bebob.c
@@ -127,8 +127,11 @@ bebob_card_free(struct snd_card *card)
{
struct snd_bebob *bebob = card->private_data;
+ snd_bebob_stream_destroy_duplex(bebob);
fw_unit_put(bebob->unit);
+ kfree(bebob->maudio_special_quirk);
+
if (bebob->card_index >= 0) {
mutex_lock(&devices_mutex);
clear_bit(bebob->card_index, devices_used);
@@ -314,10 +317,9 @@ static void bebob_remove(struct fw_unit *unit)
if (bebob == NULL)
return;
- kfree(bebob->maudio_special_quirk);
-
- snd_bebob_stream_destroy_duplex(bebob);
- snd_card_disconnect(bebob->card);
+ /* Awake bus-reset waiters. */
+ if (!completion_done(&bebob->bus_reset))
+ complete_all(&bebob->bus_reset);
/* No need to wait for releasing card object in this context. */
snd_card_free_when_closed(bebob->card);
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c
index fcca3eebc91fb5..98e4fc8121a1f4 100644
--- a/sound/firewire/bebob/bebob_stream.c
+++ b/sound/firewire/bebob/bebob_stream.c
@@ -716,14 +716,10 @@ void snd_bebob_stream_update_duplex(struct snd_bebob *bebob)
*/
void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob)
{
- mutex_lock(&bebob->mutex);
-
amdtp_stream_destroy(&bebob->rx_stream);
amdtp_stream_destroy(&bebob->tx_stream);
destroy_both_connections(bebob);
-
- mutex_unlock(&bebob->mutex);
}
/*
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index 797f0726fc7446..70a111d7f428af 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -236,6 +236,7 @@ static void dice_card_free(struct snd_card *card)
{
struct snd_dice *dice = card->private_data;
+ snd_dice_stream_destroy_duplex(dice);
snd_dice_transaction_destroy(dice);
fw_unit_put(dice->unit);
@@ -313,10 +314,6 @@ static void dice_remove(struct fw_unit *unit)
{
struct snd_dice *dice = dev_get_drvdata(&unit->device);
- snd_card_disconnect(dice->card);
-
- snd_dice_stream_destroy_duplex(dice);
-
/* No need to wait for releasing card object in this context. */
snd_card_free_when_closed(dice->card);
}
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
index 1e33394d8a930e..2682e7e3e5c985 100644
--- a/sound/firewire/fireworks/fireworks.c
+++ b/sound/firewire/fireworks/fireworks.c
@@ -184,8 +184,12 @@ efw_card_free(struct snd_card *card)
{
struct snd_efw *efw = card->private_data;
+ snd_efw_stream_destroy_duplex(efw);
+ snd_efw_transaction_remove_instance(efw);
fw_unit_put(efw->unit);
+ kfree(efw->resp_buf);
+
if (efw->card_index >= 0) {
mutex_lock(&devices_mutex);
clear_bit(efw->card_index, devices_used);
@@ -193,7 +197,6 @@ efw_card_free(struct snd_card *card)
}
mutex_destroy(&efw->mutex);
- kfree(efw->resp_buf);
}
static int
@@ -297,11 +300,6 @@ static void efw_remove(struct fw_unit *unit)
{
struct snd_efw *efw = dev_get_drvdata(&unit->device);
- snd_efw_stream_destroy_duplex(efw);
- snd_efw_transaction_remove_instance(efw);
-
- snd_card_disconnect(efw->card);
-
/* No need to wait for releasing card object in this context. */
snd_card_free_when_closed(efw->card);
}
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index f817b7ae097e28..c55db1bddc80a0 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -324,12 +324,8 @@ void snd_efw_stream_update_duplex(struct snd_efw *efw)
void snd_efw_stream_destroy_duplex(struct snd_efw *efw)
{
- mutex_lock(&efw->mutex);
-
destroy_stream(efw, &efw->rx_stream);
destroy_stream(efw, &efw->tx_stream);
-
- mutex_unlock(&efw->mutex);
}
void snd_efw_stream_lock_changed(struct snd_efw *efw)
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c
index 1607b26404c380..8c6ce019f437c3 100644
--- a/sound/firewire/oxfw/oxfw.c
+++ b/sound/firewire/oxfw/oxfw.c
@@ -115,6 +115,10 @@ static void oxfw_card_free(struct snd_card *card)
struct snd_oxfw *oxfw = card->private_data;
unsigned int i;
+ snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream);
+ if (oxfw->has_output)
+ snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream);
+
fw_unit_put(oxfw->unit);
for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
@@ -220,12 +224,6 @@ static void oxfw_remove(struct fw_unit *unit)
{
struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
- snd_card_disconnect(oxfw->card);
-
- snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream);
- if (oxfw->has_output)
- snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream);
-
/* No need to wait for releasing card object in this context. */
snd_card_free_when_closed(oxfw->card);
}