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 | ||
