@@ -184,6 +184,18 @@ get_hardware_info(struct snd_efw *efw)
184
184
return err ;
185
185
}
186
186
187
+ static void efw_free (struct snd_efw * efw )
188
+ {
189
+ snd_efw_stream_destroy_duplex (efw );
190
+ snd_efw_transaction_remove_instance (efw );
191
+ fw_unit_put (efw -> unit );
192
+
193
+ kfree (efw -> resp_buf );
194
+
195
+ mutex_destroy (& efw -> mutex );
196
+ kfree (efw );
197
+ }
198
+
187
199
/*
188
200
* This module releases the FireWire unit data after all ALSA character devices
189
201
* are released by applications. This is for releasing stream data or finishing
@@ -195,28 +207,24 @@ efw_card_free(struct snd_card *card)
195
207
{
196
208
struct snd_efw * efw = card -> private_data ;
197
209
198
- snd_efw_stream_destroy_duplex (efw );
199
- snd_efw_transaction_remove_instance (efw );
200
- fw_unit_put (efw -> unit );
201
-
202
- kfree (efw -> resp_buf );
203
-
204
210
if (efw -> card_index >= 0 ) {
205
211
mutex_lock (& devices_mutex );
206
212
clear_bit (efw -> card_index , devices_used );
207
213
mutex_unlock (& devices_mutex );
208
214
}
209
215
210
- mutex_destroy ( & efw -> mutex );
216
+ efw_free ( card -> private_data );
211
217
}
212
218
213
- static int
214
- efw_probe (struct fw_unit * unit ,
215
- const struct ieee1394_device_id * entry )
219
+ static void
220
+ do_registration (struct work_struct * work )
216
221
{
217
- struct snd_card * card ;
218
- struct snd_efw * efw ;
219
- int card_index , err ;
222
+ struct snd_efw * efw = container_of (work , struct snd_efw , dwork .work );
223
+ unsigned int card_index ;
224
+ int err ;
225
+
226
+ if (efw -> registered )
227
+ return ;
220
228
221
229
mutex_lock (& devices_mutex );
222
230
@@ -226,24 +234,16 @@ efw_probe(struct fw_unit *unit,
226
234
break ;
227
235
}
228
236
if (card_index >= SNDRV_CARDS ) {
229
- err = - ENOENT ;
230
- goto end ;
237
+ mutex_unlock ( & devices_mutex ) ;
238
+ return ;
231
239
}
232
240
233
- err = snd_card_new (& unit -> device , index [card_index ], id [card_index ],
234
- THIS_MODULE , sizeof (struct snd_efw ), & card );
235
- if (err < 0 )
236
- goto end ;
237
- efw = card -> private_data ;
238
- efw -> card_index = card_index ;
239
- set_bit (card_index , devices_used );
240
- card -> private_free = efw_card_free ;
241
-
242
- efw -> card = card ;
243
- efw -> unit = fw_unit_get (unit );
244
- mutex_init (& efw -> mutex );
245
- spin_lock_init (& efw -> lock );
246
- init_waitqueue_head (& efw -> hwdep_wait );
241
+ err = snd_card_new (& efw -> unit -> device , index [card_index ],
242
+ id [card_index ], THIS_MODULE , 0 , & efw -> card );
243
+ if (err < 0 ) {
244
+ mutex_unlock (& devices_mutex );
245
+ return ;
246
+ }
247
247
248
248
/* prepare response buffer */
249
249
snd_efw_resp_buf_size = clamp (snd_efw_resp_buf_size ,
@@ -260,6 +260,10 @@ efw_probe(struct fw_unit *unit,
260
260
if (err < 0 )
261
261
goto error ;
262
262
263
+ err = snd_efw_stream_init_duplex (efw );
264
+ if (err < 0 )
265
+ goto error ;
266
+
263
267
snd_efw_proc_init (efw );
264
268
265
269
if (efw -> midi_out_ports || efw -> midi_in_ports ) {
@@ -276,44 +280,93 @@ efw_probe(struct fw_unit *unit,
276
280
if (err < 0 )
277
281
goto error ;
278
282
279
- err = snd_efw_stream_init_duplex (efw );
283
+ err = snd_card_register (efw -> card );
280
284
if (err < 0 )
281
285
goto error ;
282
286
283
- err = snd_card_register (card );
284
- if (err < 0 ) {
285
- snd_efw_stream_destroy_duplex (efw );
286
- goto error ;
287
- }
288
-
289
- dev_set_drvdata (& unit -> device , efw );
290
- end :
287
+ set_bit (card_index , devices_used );
291
288
mutex_unlock (& devices_mutex );
292
- return err ;
289
+
290
+ /*
291
+ * After registered, efw instance can be released corresponding to
292
+ * releasing the sound card instance.
293
+ */
294
+ efw -> card -> private_free = efw_card_free ;
295
+ efw -> card -> private_data = efw ;
296
+ efw -> registered = true;
297
+
298
+ return ;
293
299
error :
294
- snd_efw_transaction_remove_instance (efw );
295
300
mutex_unlock (& devices_mutex );
296
- snd_card_free (card );
297
- return err ;
301
+ snd_efw_transaction_remove_instance (efw );
302
+ snd_efw_stream_destroy_duplex (efw );
303
+ snd_card_free (efw -> card );
304
+ dev_info (& efw -> unit -> device ,
305
+ "Sound card registration failed: %d\n" , err );
306
+ }
307
+
308
+ static int
309
+ efw_probe (struct fw_unit * unit , const struct ieee1394_device_id * entry )
310
+ {
311
+ struct snd_efw * efw ;
312
+
313
+ efw = kzalloc (sizeof (struct snd_efw ), GFP_KERNEL );
314
+ if (efw == NULL )
315
+ return - ENOMEM ;
316
+
317
+ efw -> unit = fw_unit_get (unit );
318
+ dev_set_drvdata (& unit -> device , efw );
319
+
320
+ mutex_init (& efw -> mutex );
321
+ spin_lock_init (& efw -> lock );
322
+ init_waitqueue_head (& efw -> hwdep_wait );
323
+
324
+ /* Allocate and register this sound card later. */
325
+ INIT_DEFERRABLE_WORK (& efw -> dwork , do_registration );
326
+ snd_fw_schedule_registration (unit , & efw -> dwork );
327
+
328
+ return 0 ;
298
329
}
299
330
300
331
static void efw_update (struct fw_unit * unit )
301
332
{
302
333
struct snd_efw * efw = dev_get_drvdata (& unit -> device );
303
334
335
+ /* Postpone a workqueue for deferred registration. */
336
+ if (!efw -> registered )
337
+ snd_fw_schedule_registration (unit , & efw -> dwork );
338
+
304
339
snd_efw_transaction_bus_reset (efw -> unit );
305
340
306
- mutex_lock (& efw -> mutex );
307
- snd_efw_stream_update_duplex (efw );
308
- mutex_unlock (& efw -> mutex );
341
+ /*
342
+ * After registration, userspace can start packet streaming, then this
343
+ * code block works fine.
344
+ */
345
+ if (efw -> registered ) {
346
+ mutex_lock (& efw -> mutex );
347
+ snd_efw_stream_update_duplex (efw );
348
+ mutex_unlock (& efw -> mutex );
349
+ }
309
350
}
310
351
311
352
static void efw_remove (struct fw_unit * unit )
312
353
{
313
354
struct snd_efw * efw = dev_get_drvdata (& unit -> device );
314
355
315
- /* No need to wait for releasing card object in this context. */
316
- snd_card_free_when_closed (efw -> card );
356
+ /*
357
+ * Confirm to stop the work for registration before the sound card is
358
+ * going to be released. The work is not scheduled again because bus
359
+ * reset handler is not called anymore.
360
+ */
361
+ cancel_delayed_work_sync (& efw -> dwork );
362
+
363
+ if (efw -> registered ) {
364
+ /* No need to wait for releasing card object in this context. */
365
+ snd_card_free_when_closed (efw -> card );
366
+ } else {
367
+ /* Don't forget this case. */
368
+ efw_free (efw );
369
+ }
317
370
}
318
371
319
372
static const struct ieee1394_device_id efw_id_table [] = {
0 commit comments