summaryrefslogtreecommitdiffstats
path: root/sound/firewire/fireworks/fireworks.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/firewire/fireworks/fireworks.c')
-rw-r--r--sound/firewire/fireworks/fireworks.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
index 3e2ed8e82cbc..2682e7e3e5c9 100644
--- a/sound/firewire/fireworks/fireworks.c
+++ b/sound/firewire/fireworks/fireworks.c
@@ -173,11 +173,23 @@ end:
return err;
}
+/*
+ * This module releases the FireWire unit data after all ALSA character devices
+ * are released by applications. This is for releasing stream data or finishing
+ * transactions safely. Thus at returning from .remove(), this module still keep
+ * references for the unit.
+ */
static void
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);
@@ -185,7 +197,6 @@ efw_card_free(struct snd_card *card)
}
mutex_destroy(&efw->mutex);
- kfree(efw->resp_buf);
}
static int
@@ -218,7 +229,7 @@ efw_probe(struct fw_unit *unit,
card->private_free = efw_card_free;
efw->card = card;
- efw->unit = unit;
+ efw->unit = fw_unit_get(unit);
mutex_init(&efw->mutex);
spin_lock_init(&efw->lock);
init_waitqueue_head(&efw->hwdep_wait);
@@ -289,10 +300,7 @@ 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);
}