From 53fb1e63599438bd5f6fbb852023d80916d83983 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 28 Dec 2008 16:32:08 +0100 Subject: ALSA: Introduce snd_card_create() Introduced snd_card_create() function as a replacement of snd_card_new(). The new function returns a negative error code so that the probe callback can return the proper error code, while snd_card_new() can give only NULL check. The old snd_card_new() is still provided as an inline function but with __deprecated attribute. It'll be removed soon later. Signed-off-by: Takashi Iwai --- sound/core/init.c | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'sound/core/init.c') diff --git a/sound/core/init.c b/sound/core/init.c index 0d5520c415d3..dc4b80c7f311 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -121,31 +121,44 @@ static inline int init_info_for_card(struct snd_card *card) #endif /** - * snd_card_new - create and initialize a soundcard structure + * snd_card_create - create and initialize a soundcard structure * @idx: card index (address) [0 ... (SNDRV_CARDS-1)] * @xid: card identification (ASCII string) * @module: top level module for locking * @extra_size: allocate this extra size after the main soundcard structure + * @card_ret: the pointer to store the created card instance * * Creates and initializes a soundcard structure. * - * Returns kmallocated snd_card structure. Creates the ALSA control interface - * (which is blocked until snd_card_register function is called). + * The function allocates snd_card instance via kzalloc with the given + * space for the driver to use freely. The allocated struct is stored + * in the given card_ret pointer. + * + * Returns zero if successful or a negative error code. */ -struct snd_card *snd_card_new(int idx, const char *xid, - struct module *module, int extra_size) +int snd_card_create(int idx, const char *xid, + struct module *module, int extra_size, + struct snd_card **card_ret) { struct snd_card *card; int err, idx2; + if (snd_BUG_ON(!card_ret)) + return -EINVAL; + *card_ret = NULL; + if (extra_size < 0) extra_size = 0; card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL); - if (card == NULL) - return NULL; + if (!card) + return -ENOMEM; if (xid) { - if (!snd_info_check_reserved_words(xid)) + if (!snd_info_check_reserved_words(xid)) { + snd_printk(KERN_ERR + "given id string '%s' is reserved.\n", xid); + err = -EBUSY; goto __error; + } strlcpy(card->id, xid, sizeof(card->id)); } err = 0; @@ -202,26 +215,28 @@ struct snd_card *snd_card_new(int idx, const char *xid, #endif /* the control interface cannot be accessed from the user space until */ /* snd_cards_bitmask and snd_cards are set with snd_card_register */ - if ((err = snd_ctl_create(card)) < 0) { - snd_printd("unable to register control minors\n"); + err = snd_ctl_create(card); + if (err < 0) { + snd_printk(KERN_ERR "unable to register control minors\n"); goto __error; } - if ((err = snd_info_card_create(card)) < 0) { - snd_printd("unable to create card info\n"); + err = snd_info_card_create(card); + if (err < 0) { + snd_printk(KERN_ERR "unable to create card info\n"); goto __error_ctl; } if (extra_size > 0) card->private_data = (char *)card + sizeof(struct snd_card); - return card; + *card_ret = card; + return 0; __error_ctl: snd_device_free_all(card, SNDRV_DEV_CMD_PRE); __error: kfree(card); - return NULL; + return err; } - -EXPORT_SYMBOL(snd_card_new); +EXPORT_SYMBOL(snd_card_create); /* return non-zero if a card is already locked */ int snd_card_locked(int card) -- cgit v1.2.3 From 118dd6bfe7e0cddc8ab417ead19cc76000e92773 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 23 Feb 2009 16:35:21 +0100 Subject: ALSA: Clean up snd_monitor_file management Use the standard linked list for snd_monitor_file management. Also, move the list deletion of shutdown_list element into snd_disconnect_release() (for simplification). Signed-off-by: Takashi Iwai --- sound/core/init.c | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) (limited to 'sound/core/init.c') diff --git a/sound/core/init.c b/sound/core/init.c index 0d5520c415d3..05c6da554cbf 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -195,6 +195,7 @@ struct snd_card *snd_card_new(int idx, const char *xid, INIT_LIST_HEAD(&card->controls); INIT_LIST_HEAD(&card->ctl_files); spin_lock_init(&card->files_lock); + INIT_LIST_HEAD(&card->files_list); init_waitqueue_head(&card->shutdown_sleep); #ifdef CONFIG_PM mutex_init(&card->power_lock); @@ -259,6 +260,7 @@ static int snd_disconnect_release(struct inode *inode, struct file *file) list_for_each_entry(_df, &shutdown_files, shutdown_list) { if (_df->file == file) { df = _df; + list_del_init(&df->shutdown_list); break; } } @@ -347,8 +349,7 @@ int snd_card_disconnect(struct snd_card *card) /* phase 2: replace file->f_op with special dummy operations */ spin_lock(&card->files_lock); - mfile = card->files; - while (mfile) { + list_for_each_entry(mfile, &card->files_list, list) { file = mfile->file; /* it's critical part, use endless loop */ @@ -361,8 +362,6 @@ int snd_card_disconnect(struct snd_card *card) mfile->file->f_op = &snd_shutdown_f_ops; fops_get(mfile->file->f_op); - - mfile = mfile->next; } spin_unlock(&card->files_lock); @@ -442,7 +441,7 @@ int snd_card_free_when_closed(struct snd_card *card) return ret; spin_lock(&card->files_lock); - if (card->files == NULL) + if (list_empty(&card->files_list)) free_now = 1; else card->free_on_last_close = 1; @@ -462,7 +461,7 @@ int snd_card_free(struct snd_card *card) return ret; /* wait, until all devices are ready for the free operation */ - wait_event(card->shutdown_sleep, card->files == NULL); + wait_event(card->shutdown_sleep, list_empty(&card->files_list)); snd_card_do_free(card); return 0; } @@ -809,15 +808,13 @@ int snd_card_file_add(struct snd_card *card, struct file *file) return -ENOMEM; mfile->file = file; mfile->disconnected_f_op = NULL; - mfile->next = NULL; spin_lock(&card->files_lock); if (card->shutdown) { spin_unlock(&card->files_lock); kfree(mfile); return -ENODEV; } - mfile->next = card->files; - card->files = mfile; + list_add(&mfile->list, &card->files_list); spin_unlock(&card->files_lock); return 0; } @@ -839,29 +836,20 @@ EXPORT_SYMBOL(snd_card_file_add); */ int snd_card_file_remove(struct snd_card *card, struct file *file) { - struct snd_monitor_file *mfile, *pfile = NULL; + struct snd_monitor_file *mfile, *found = NULL; int last_close = 0; spin_lock(&card->files_lock); - mfile = card->files; - while (mfile) { + list_for_each_entry(mfile, &card->files_list, list) { if (mfile->file == file) { - if (pfile) - pfile->next = mfile->next; - else - card->files = mfile->next; + list_del(&mfile->list); + if (mfile->disconnected_f_op) + fops_put(mfile->disconnected_f_op); + found = mfile; break; } - pfile = mfile; - mfile = mfile->next; - } - if (mfile && mfile->disconnected_f_op) { - fops_put(mfile->disconnected_f_op); - spin_lock(&shutdown_lock); - list_del(&mfile->shutdown_list); - spin_unlock(&shutdown_lock); } - if (card->files == NULL) + if (list_empty(&card->files_list)) last_close = 1; spin_unlock(&card->files_lock); if (last_close) { @@ -869,11 +857,11 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) if (card->free_on_last_close) snd_card_do_free(card); } - if (!mfile) { + if (!found) { snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file); return -ENOENT; } - kfree(mfile); + kfree(found); return 0; } -- cgit v1.2.3