diff options
Diffstat (limited to 'sound/firewire/bebob/bebob.c')
-rw-r--r-- | sound/firewire/bebob/bebob.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c index fc19c99654aa..611b7dae7ee5 100644 --- a/sound/firewire/bebob/bebob.c +++ b/sound/firewire/bebob/bebob.c | |||
@@ -116,11 +116,22 @@ end: | |||
116 | return err; | 116 | return err; |
117 | } | 117 | } |
118 | 118 | ||
119 | /* | ||
120 | * This module releases the FireWire unit data after all ALSA character devices | ||
121 | * are released by applications. This is for releasing stream data or finishing | ||
122 | * transactions safely. Thus at returning from .remove(), this module still keep | ||
123 | * references for the unit. | ||
124 | */ | ||
119 | static void | 125 | static void |
120 | bebob_card_free(struct snd_card *card) | 126 | bebob_card_free(struct snd_card *card) |
121 | { | 127 | { |
122 | struct snd_bebob *bebob = card->private_data; | 128 | struct snd_bebob *bebob = card->private_data; |
123 | 129 | ||
130 | snd_bebob_stream_destroy_duplex(bebob); | ||
131 | fw_unit_put(bebob->unit); | ||
132 | |||
133 | kfree(bebob->maudio_special_quirk); | ||
134 | |||
124 | if (bebob->card_index >= 0) { | 135 | if (bebob->card_index >= 0) { |
125 | mutex_lock(&devices_mutex); | 136 | mutex_lock(&devices_mutex); |
126 | clear_bit(bebob->card_index, devices_used); | 137 | clear_bit(bebob->card_index, devices_used); |
@@ -205,7 +216,7 @@ bebob_probe(struct fw_unit *unit, | |||
205 | card->private_free = bebob_card_free; | 216 | card->private_free = bebob_card_free; |
206 | 217 | ||
207 | bebob->card = card; | 218 | bebob->card = card; |
208 | bebob->unit = unit; | 219 | bebob->unit = fw_unit_get(unit); |
209 | bebob->spec = spec; | 220 | bebob->spec = spec; |
210 | mutex_init(&bebob->mutex); | 221 | mutex_init(&bebob->mutex); |
211 | spin_lock_init(&bebob->lock); | 222 | spin_lock_init(&bebob->lock); |
@@ -306,10 +317,11 @@ static void bebob_remove(struct fw_unit *unit) | |||
306 | if (bebob == NULL) | 317 | if (bebob == NULL) |
307 | return; | 318 | return; |
308 | 319 | ||
309 | kfree(bebob->maudio_special_quirk); | 320 | /* Awake bus-reset waiters. */ |
321 | if (!completion_done(&bebob->bus_reset)) | ||
322 | complete_all(&bebob->bus_reset); | ||
310 | 323 | ||
311 | snd_bebob_stream_destroy_duplex(bebob); | 324 | /* No need to wait for releasing card object in this context. */ |
312 | snd_card_disconnect(bebob->card); | ||
313 | snd_card_free_when_closed(bebob->card); | 325 | snd_card_free_when_closed(bebob->card); |
314 | } | 326 | } |
315 | 327 | ||