diff options
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/init.c | 23 | ||||
-rw-r--r-- | sound/core/oss/mixer_oss.c | 16 | ||||
-rw-r--r-- | sound/core/sound.c | 5 |
3 files changed, 37 insertions, 7 deletions
diff --git a/sound/core/init.c b/sound/core/init.c index 0c4dc40376a7..356d41e4f3a4 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -49,8 +49,7 @@ static const struct file_operations snd_shutdown_f_ops; /* locked for registering/using */ static DECLARE_BITMAP(snd_cards_lock, SNDRV_CARDS); -struct snd_card *snd_cards[SNDRV_CARDS]; -EXPORT_SYMBOL(snd_cards); +static struct snd_card *snd_cards[SNDRV_CARDS]; static DEFINE_MUTEX(snd_card_mutex); @@ -268,6 +267,26 @@ int snd_card_new(struct device *parent, int idx, const char *xid, } EXPORT_SYMBOL(snd_card_new); +/** + * snd_card_ref - Get the card object from the index + * @idx: the card index + * + * Returns a card object corresponding to the given index or NULL if not found. + * Release the object via snd_card_unref(). + */ +struct snd_card *snd_card_ref(int idx) +{ + struct snd_card *card; + + mutex_lock(&snd_card_mutex); + card = snd_cards[idx]; + if (card) + get_device(&card->card_dev); + mutex_unlock(&snd_card_mutex); + return card; +} +EXPORT_SYMBOL_GPL(snd_card_ref); + /* return non-zero if a card is already locked */ int snd_card_locked(int card) { diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 64d904bee8bb..c8618678649c 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -1403,24 +1403,32 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd) static int __init alsa_mixer_oss_init(void) { + struct snd_card *card; int idx; snd_mixer_oss_notify_callback = snd_mixer_oss_notify_handler; for (idx = 0; idx < SNDRV_CARDS; idx++) { - if (snd_cards[idx]) - snd_mixer_oss_notify_handler(snd_cards[idx], SND_MIXER_OSS_NOTIFY_REGISTER); + card = snd_card_ref(idx); + if (card) { + snd_mixer_oss_notify_handler(card, SND_MIXER_OSS_NOTIFY_REGISTER); + snd_card_unref(card); + } } return 0; } static void __exit alsa_mixer_oss_exit(void) { + struct snd_card *card; int idx; snd_mixer_oss_notify_callback = NULL; for (idx = 0; idx < SNDRV_CARDS; idx++) { - if (snd_cards[idx]) - snd_mixer_oss_notify_handler(snd_cards[idx], SND_MIXER_OSS_NOTIFY_FREE); + card = snd_card_ref(idx); + if (card) { + snd_mixer_oss_notify_handler(card, SND_MIXER_OSS_NOTIFY_FREE); + snd_card_unref(card); + } } } diff --git a/sound/core/sound.c b/sound/core/sound.c index b30f027eb0fe..a9ad4379523b 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -134,8 +134,11 @@ static struct snd_minor *autoload_device(unsigned int minor) if (dev == SNDRV_MINOR_CONTROL) { /* /dev/aloadC? */ int card = SNDRV_MINOR_CARD(minor); - if (snd_cards[card] == NULL) + struct snd_card *ref = snd_card_ref(card); + if (!ref) snd_request_card(card); + else + snd_card_unref(ref); } else if (dev == SNDRV_MINOR_GLOBAL) { /* /dev/aloadSEQ */ snd_request_other(minor); |