Skip to content

Commit dec8431

Browse files
takaswietiwai
authored andcommitted
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>
1 parent d23c2cc commit dec8431

File tree

6 files changed

+15
-28
lines changed

6 files changed

+15
-28
lines changed

sound/firewire/bebob/bebob.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,11 @@ bebob_card_free(struct snd_card *card)
127127
{
128128
struct snd_bebob *bebob = card->private_data;
129129

130+
snd_bebob_stream_destroy_duplex(bebob);
130131
fw_unit_put(bebob->unit);
131132

133+
kfree(bebob->maudio_special_quirk);
134+
132135
if (bebob->card_index >= 0) {
133136
mutex_lock(&devices_mutex);
134137
clear_bit(bebob->card_index, devices_used);
@@ -314,10 +317,9 @@ static void bebob_remove(struct fw_unit *unit)
314317
if (bebob == NULL)
315318
return;
316319

317-
kfree(bebob->maudio_special_quirk);
318-
319-
snd_bebob_stream_destroy_duplex(bebob);
320-
snd_card_disconnect(bebob->card);
320+
/* Awake bus-reset waiters. */
321+
if (!completion_done(&bebob->bus_reset))
322+
complete_all(&bebob->bus_reset);
321323

322324
/* No need to wait for releasing card object in this context. */
323325
snd_card_free_when_closed(bebob->card);

sound/firewire/bebob/bebob_stream.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -716,14 +716,10 @@ void snd_bebob_stream_update_duplex(struct snd_bebob *bebob)
716716
*/
717717
void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob)
718718
{
719-
mutex_lock(&bebob->mutex);
720-
721719
amdtp_stream_destroy(&bebob->rx_stream);
722720
amdtp_stream_destroy(&bebob->tx_stream);
723721

724722
destroy_both_connections(bebob);
725-
726-
mutex_unlock(&bebob->mutex);
727723
}
728724

729725
/*

sound/firewire/dice/dice.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ static void dice_card_free(struct snd_card *card)
236236
{
237237
struct snd_dice *dice = card->private_data;
238238

239+
snd_dice_stream_destroy_duplex(dice);
239240
snd_dice_transaction_destroy(dice);
240241
fw_unit_put(dice->unit);
241242

@@ -313,10 +314,6 @@ static void dice_remove(struct fw_unit *unit)
313314
{
314315
struct snd_dice *dice = dev_get_drvdata(&unit->device);
315316

316-
snd_card_disconnect(dice->card);
317-
318-
snd_dice_stream_destroy_duplex(dice);
319-
320317
/* No need to wait for releasing card object in this context. */
321318
snd_card_free_when_closed(dice->card);
322319
}

sound/firewire/fireworks/fireworks.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,16 +184,19 @@ efw_card_free(struct snd_card *card)
184184
{
185185
struct snd_efw *efw = card->private_data;
186186

187+
snd_efw_stream_destroy_duplex(efw);
188+
snd_efw_transaction_remove_instance(efw);
187189
fw_unit_put(efw->unit);
188190

191+
kfree(efw->resp_buf);
192+
189193
if (efw->card_index >= 0) {
190194
mutex_lock(&devices_mutex);
191195
clear_bit(efw->card_index, devices_used);
192196
mutex_unlock(&devices_mutex);
193197
}
194198

195199
mutex_destroy(&efw->mutex);
196-
kfree(efw->resp_buf);
197200
}
198201

199202
static int
@@ -297,11 +300,6 @@ static void efw_remove(struct fw_unit *unit)
297300
{
298301
struct snd_efw *efw = dev_get_drvdata(&unit->device);
299302

300-
snd_efw_stream_destroy_duplex(efw);
301-
snd_efw_transaction_remove_instance(efw);
302-
303-
snd_card_disconnect(efw->card);
304-
305303
/* No need to wait for releasing card object in this context. */
306304
snd_card_free_when_closed(efw->card);
307305
}

sound/firewire/fireworks/fireworks_stream.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,8 @@ void snd_efw_stream_update_duplex(struct snd_efw *efw)
324324

325325
void snd_efw_stream_destroy_duplex(struct snd_efw *efw)
326326
{
327-
mutex_lock(&efw->mutex);
328-
329327
destroy_stream(efw, &efw->rx_stream);
330328
destroy_stream(efw, &efw->tx_stream);
331-
332-
mutex_unlock(&efw->mutex);
333329
}
334330

335331
void snd_efw_stream_lock_changed(struct snd_efw *efw)

sound/firewire/oxfw/oxfw.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ static void oxfw_card_free(struct snd_card *card)
115115
struct snd_oxfw *oxfw = card->private_data;
116116
unsigned int i;
117117

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+
118122
fw_unit_put(oxfw->unit);
119123

120124
for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
@@ -220,12 +224,6 @@ static void oxfw_remove(struct fw_unit *unit)
220224
{
221225
struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
222226

223-
snd_card_disconnect(oxfw->card);
224-
225-
snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream);
226-
if (oxfw->has_output)
227-
snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream);
228-
229227
/* No need to wait for releasing card object in this context. */
230228
snd_card_free_when_closed(oxfw->card);
231229
}

0 commit comments

Comments
 (0)