diff options
Diffstat (limited to 'sound/firewire/oxfw/oxfw.c')
-rw-r--r-- | sound/firewire/oxfw/oxfw.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c index 60e5cad0531a..8c6ce019f437 100644 --- a/sound/firewire/oxfw/oxfw.c +++ b/sound/firewire/oxfw/oxfw.c | |||
@@ -104,11 +104,23 @@ end: | |||
104 | return err; | 104 | return err; |
105 | } | 105 | } |
106 | 106 | ||
107 | /* | ||
108 | * This module releases the FireWire unit data after all ALSA character devices | ||
109 | * are released by applications. This is for releasing stream data or finishing | ||
110 | * transactions safely. Thus at returning from .remove(), this module still keep | ||
111 | * references for the unit. | ||
112 | */ | ||
107 | static void oxfw_card_free(struct snd_card *card) | 113 | static void oxfw_card_free(struct snd_card *card) |
108 | { | 114 | { |
109 | struct snd_oxfw *oxfw = card->private_data; | 115 | struct snd_oxfw *oxfw = card->private_data; |
110 | unsigned int i; | 116 | unsigned int i; |
111 | 117 | ||
118 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); | ||
119 | if (oxfw->has_output) | ||
120 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); | ||
121 | |||
122 | fw_unit_put(oxfw->unit); | ||
123 | |||
112 | for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { | 124 | for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { |
113 | kfree(oxfw->tx_stream_formats[i]); | 125 | kfree(oxfw->tx_stream_formats[i]); |
114 | kfree(oxfw->rx_stream_formats[i]); | 126 | kfree(oxfw->rx_stream_formats[i]); |
@@ -136,7 +148,7 @@ static int oxfw_probe(struct fw_unit *unit, | |||
136 | oxfw = card->private_data; | 148 | oxfw = card->private_data; |
137 | oxfw->card = card; | 149 | oxfw->card = card; |
138 | mutex_init(&oxfw->mutex); | 150 | mutex_init(&oxfw->mutex); |
139 | oxfw->unit = unit; | 151 | oxfw->unit = fw_unit_get(unit); |
140 | oxfw->device_info = (const struct device_info *)id->driver_data; | 152 | oxfw->device_info = (const struct device_info *)id->driver_data; |
141 | spin_lock_init(&oxfw->lock); | 153 | spin_lock_init(&oxfw->lock); |
142 | init_waitqueue_head(&oxfw->hwdep_wait); | 154 | init_waitqueue_head(&oxfw->hwdep_wait); |
@@ -212,12 +224,7 @@ static void oxfw_remove(struct fw_unit *unit) | |||
212 | { | 224 | { |
213 | struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); | 225 | struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); |
214 | 226 | ||
215 | snd_card_disconnect(oxfw->card); | 227 | /* No need to wait for releasing card object in this context. */ |
216 | |||
217 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); | ||
218 | if (oxfw->has_output) | ||
219 | snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); | ||
220 | |||
221 | snd_card_free_when_closed(oxfw->card); | 228 | snd_card_free_when_closed(oxfw->card); |
222 | } | 229 | } |
223 | 230 | ||