diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-06-23 08:38:23 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-09-23 04:36:58 -0400 |
commit | c461482c8072bb073e6146db320d3da85cdc89ad (patch) | |
tree | 3b69cfd292a488a8cb57ac9b040bd2b1b1a1e26d /sound/core/control.c | |
parent | 746d4a02e68499fc6c1f8d0c43d2271853ade181 (diff) |
[ALSA] Unregister device files at disconnection
Orignally proposed by Sam Revitch <sam.revitch@gmail.com>.
Unregister device files at disconnection to avoid the futher accesses.
Also, the dev_unregister callback is removed and replaced with the
combination of disconnect + free.
A new function snd_card_free_when_closed() is introduced, which is
used in USB disconnect callback.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/core/control.c')
-rw-r--r-- | sound/core/control.c | 27 |
1 files changed, 9 insertions, 18 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index e9c8854d2f7b..f0c7272a2d48 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -1375,6 +1375,11 @@ static int snd_ctl_dev_disconnect(struct snd_device *device) | |||
1375 | struct snd_card *card = device->device_data; | 1375 | struct snd_card *card = device->device_data; |
1376 | struct list_head *flist; | 1376 | struct list_head *flist; |
1377 | struct snd_ctl_file *ctl; | 1377 | struct snd_ctl_file *ctl; |
1378 | int err, cardnum; | ||
1379 | |||
1380 | snd_assert(card != NULL, return -ENXIO); | ||
1381 | cardnum = card->number; | ||
1382 | snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO); | ||
1378 | 1383 | ||
1379 | down_read(&card->controls_rwsem); | 1384 | down_read(&card->controls_rwsem); |
1380 | list_for_each(flist, &card->ctl_files) { | 1385 | list_for_each(flist, &card->ctl_files) { |
@@ -1383,6 +1388,10 @@ static int snd_ctl_dev_disconnect(struct snd_device *device) | |||
1383 | kill_fasync(&ctl->fasync, SIGIO, POLL_ERR); | 1388 | kill_fasync(&ctl->fasync, SIGIO, POLL_ERR); |
1384 | } | 1389 | } |
1385 | up_read(&card->controls_rwsem); | 1390 | up_read(&card->controls_rwsem); |
1391 | |||
1392 | if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL, | ||
1393 | card, -1)) < 0) | ||
1394 | return err; | ||
1386 | return 0; | 1395 | return 0; |
1387 | } | 1396 | } |
1388 | 1397 | ||
@@ -1404,23 +1413,6 @@ static int snd_ctl_dev_free(struct snd_device *device) | |||
1404 | } | 1413 | } |
1405 | 1414 | ||
1406 | /* | 1415 | /* |
1407 | * de-registration of the control device | ||
1408 | */ | ||
1409 | static int snd_ctl_dev_unregister(struct snd_device *device) | ||
1410 | { | ||
1411 | struct snd_card *card = device->device_data; | ||
1412 | int err, cardnum; | ||
1413 | |||
1414 | snd_assert(card != NULL, return -ENXIO); | ||
1415 | cardnum = card->number; | ||
1416 | snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO); | ||
1417 | if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL, | ||
1418 | card, -1)) < 0) | ||
1419 | return err; | ||
1420 | return snd_ctl_dev_free(device); | ||
1421 | } | ||
1422 | |||
1423 | /* | ||
1424 | * create control core: | 1416 | * create control core: |
1425 | * called from init.c | 1417 | * called from init.c |
1426 | */ | 1418 | */ |
@@ -1430,7 +1422,6 @@ int snd_ctl_create(struct snd_card *card) | |||
1430 | .dev_free = snd_ctl_dev_free, | 1422 | .dev_free = snd_ctl_dev_free, |
1431 | .dev_register = snd_ctl_dev_register, | 1423 | .dev_register = snd_ctl_dev_register, |
1432 | .dev_disconnect = snd_ctl_dev_disconnect, | 1424 | .dev_disconnect = snd_ctl_dev_disconnect, |
1433 | .dev_unregister = snd_ctl_dev_unregister | ||
1434 | }; | 1425 | }; |
1435 | 1426 | ||
1436 | snd_assert(card != NULL, return -ENXIO); | 1427 | snd_assert(card != NULL, return -ENXIO); |