aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/init.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-03-28 20:22:18 -0400
committerDave Airlie <airlied@redhat.com>2009-03-28 20:22:18 -0400
commit90f959bcb386da2c71613dcefc6a285e054a539e (patch)
treeee3e9dd4111d4aad12e579cb0c2c159114dff263 /sound/core/init.c
parent41f13fe81dd1b08723ab9f3fc3c7f29cfa81f1a5 (diff)
parent07d43ba98621f08e252a48c96b258b4d572b0257 (diff)
drm: merge Linux master into HEAD
Conflicts: drivers/gpu/drm/drm_info.c drivers/gpu/drm/drm_proc.c drivers/gpu/drm/i915/i915_gem_debugfs.c
Diffstat (limited to 'sound/core/init.c')
-rw-r--r--sound/core/init.c89
1 files changed, 46 insertions, 43 deletions
diff --git a/sound/core/init.c b/sound/core/init.c
index 0d5520c415d3..fd56afe846ed 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)
121#endif 121#endif
122 122
123/** 123/**
124 * snd_card_new - create and initialize a soundcard structure 124 * snd_card_create - create and initialize a soundcard structure
125 * @idx: card index (address) [0 ... (SNDRV_CARDS-1)] 125 * @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
126 * @xid: card identification (ASCII string) 126 * @xid: card identification (ASCII string)
127 * @module: top level module for locking 127 * @module: top level module for locking
128 * @extra_size: allocate this extra size after the main soundcard structure 128 * @extra_size: allocate this extra size after the main soundcard structure
129 * @card_ret: the pointer to store the created card instance
129 * 130 *
130 * Creates and initializes a soundcard structure. 131 * Creates and initializes a soundcard structure.
131 * 132 *
132 * Returns kmallocated snd_card structure. Creates the ALSA control interface 133 * The function allocates snd_card instance via kzalloc with the given
133 * (which is blocked until snd_card_register function is called). 134 * space for the driver to use freely. The allocated struct is stored
135 * in the given card_ret pointer.
136 *
137 * Returns zero if successful or a negative error code.
134 */ 138 */
135struct snd_card *snd_card_new(int idx, const char *xid, 139int snd_card_create(int idx, const char *xid,
136 struct module *module, int extra_size) 140 struct module *module, int extra_size,
141 struct snd_card **card_ret)
137{ 142{
138 struct snd_card *card; 143 struct snd_card *card;
139 int err, idx2; 144 int err, idx2;
140 145
146 if (snd_BUG_ON(!card_ret))
147 return -EINVAL;
148 *card_ret = NULL;
149
141 if (extra_size < 0) 150 if (extra_size < 0)
142 extra_size = 0; 151 extra_size = 0;
143 card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL); 152 card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
144 if (card == NULL) 153 if (!card)
145 return NULL; 154 return -ENOMEM;
146 if (xid) { 155 if (xid) {
147 if (!snd_info_check_reserved_words(xid)) 156 if (!snd_info_check_reserved_words(xid)) {
157 snd_printk(KERN_ERR
158 "given id string '%s' is reserved.\n", xid);
159 err = -EBUSY;
148 goto __error; 160 goto __error;
161 }
149 strlcpy(card->id, xid, sizeof(card->id)); 162 strlcpy(card->id, xid, sizeof(card->id));
150 } 163 }
151 err = 0; 164 err = 0;
@@ -195,6 +208,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
195 INIT_LIST_HEAD(&card->controls); 208 INIT_LIST_HEAD(&card->controls);
196 INIT_LIST_HEAD(&card->ctl_files); 209 INIT_LIST_HEAD(&card->ctl_files);
197 spin_lock_init(&card->files_lock); 210 spin_lock_init(&card->files_lock);
211 INIT_LIST_HEAD(&card->files_list);
198 init_waitqueue_head(&card->shutdown_sleep); 212 init_waitqueue_head(&card->shutdown_sleep);
199#ifdef CONFIG_PM 213#ifdef CONFIG_PM
200 mutex_init(&card->power_lock); 214 mutex_init(&card->power_lock);
@@ -202,26 +216,28 @@ struct snd_card *snd_card_new(int idx, const char *xid,
202#endif 216#endif
203 /* the control interface cannot be accessed from the user space until */ 217 /* the control interface cannot be accessed from the user space until */
204 /* snd_cards_bitmask and snd_cards are set with snd_card_register */ 218 /* snd_cards_bitmask and snd_cards are set with snd_card_register */
205 if ((err = snd_ctl_create(card)) < 0) { 219 err = snd_ctl_create(card);
206 snd_printd("unable to register control minors\n"); 220 if (err < 0) {
221 snd_printk(KERN_ERR "unable to register control minors\n");
207 goto __error; 222 goto __error;
208 } 223 }
209 if ((err = snd_info_card_create(card)) < 0) { 224 err = snd_info_card_create(card);
210 snd_printd("unable to create card info\n"); 225 if (err < 0) {
226 snd_printk(KERN_ERR "unable to create card info\n");
211 goto __error_ctl; 227 goto __error_ctl;
212 } 228 }
213 if (extra_size > 0) 229 if (extra_size > 0)
214 card->private_data = (char *)card + sizeof(struct snd_card); 230 card->private_data = (char *)card + sizeof(struct snd_card);
215 return card; 231 *card_ret = card;
232 return 0;
216 233
217 __error_ctl: 234 __error_ctl:
218 snd_device_free_all(card, SNDRV_DEV_CMD_PRE); 235 snd_device_free_all(card, SNDRV_DEV_CMD_PRE);
219 __error: 236 __error:
220 kfree(card); 237 kfree(card);
221 return NULL; 238 return err;
222} 239}
223 240EXPORT_SYMBOL(snd_card_create);
224EXPORT_SYMBOL(snd_card_new);
225 241
226/* return non-zero if a card is already locked */ 242/* return non-zero if a card is already locked */
227int snd_card_locked(int card) 243int snd_card_locked(int card)
@@ -259,6 +275,7 @@ static int snd_disconnect_release(struct inode *inode, struct file *file)
259 list_for_each_entry(_df, &shutdown_files, shutdown_list) { 275 list_for_each_entry(_df, &shutdown_files, shutdown_list) {
260 if (_df->file == file) { 276 if (_df->file == file) {
261 df = _df; 277 df = _df;
278 list_del_init(&df->shutdown_list);
262 break; 279 break;
263 } 280 }
264 } 281 }
@@ -347,8 +364,7 @@ int snd_card_disconnect(struct snd_card *card)
347 /* phase 2: replace file->f_op with special dummy operations */ 364 /* phase 2: replace file->f_op with special dummy operations */
348 365
349 spin_lock(&card->files_lock); 366 spin_lock(&card->files_lock);
350 mfile = card->files; 367 list_for_each_entry(mfile, &card->files_list, list) {
351 while (mfile) {
352 file = mfile->file; 368 file = mfile->file;
353 369
354 /* it's critical part, use endless loop */ 370 /* it's critical part, use endless loop */
@@ -361,8 +377,6 @@ int snd_card_disconnect(struct snd_card *card)
361 377
362 mfile->file->f_op = &snd_shutdown_f_ops; 378 mfile->file->f_op = &snd_shutdown_f_ops;
363 fops_get(mfile->file->f_op); 379 fops_get(mfile->file->f_op);
364
365 mfile = mfile->next;
366 } 380 }
367 spin_unlock(&card->files_lock); 381 spin_unlock(&card->files_lock);
368 382
@@ -442,7 +456,7 @@ int snd_card_free_when_closed(struct snd_card *card)
442 return ret; 456 return ret;
443 457
444 spin_lock(&card->files_lock); 458 spin_lock(&card->files_lock);
445 if (card->files == NULL) 459 if (list_empty(&card->files_list))
446 free_now = 1; 460 free_now = 1;
447 else 461 else
448 card->free_on_last_close = 1; 462 card->free_on_last_close = 1;
@@ -462,7 +476,7 @@ int snd_card_free(struct snd_card *card)
462 return ret; 476 return ret;
463 477
464 /* wait, until all devices are ready for the free operation */ 478 /* wait, until all devices are ready for the free operation */
465 wait_event(card->shutdown_sleep, card->files == NULL); 479 wait_event(card->shutdown_sleep, list_empty(&card->files_list));
466 snd_card_do_free(card); 480 snd_card_do_free(card);
467 return 0; 481 return 0;
468} 482}
@@ -809,15 +823,13 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
809 return -ENOMEM; 823 return -ENOMEM;
810 mfile->file = file; 824 mfile->file = file;
811 mfile->disconnected_f_op = NULL; 825 mfile->disconnected_f_op = NULL;
812 mfile->next = NULL;
813 spin_lock(&card->files_lock); 826 spin_lock(&card->files_lock);
814 if (card->shutdown) { 827 if (card->shutdown) {
815 spin_unlock(&card->files_lock); 828 spin_unlock(&card->files_lock);
816 kfree(mfile); 829 kfree(mfile);
817 return -ENODEV; 830 return -ENODEV;
818 } 831 }
819 mfile->next = card->files; 832 list_add(&mfile->list, &card->files_list);
820 card->files = mfile;
821 spin_unlock(&card->files_lock); 833 spin_unlock(&card->files_lock);
822 return 0; 834 return 0;
823} 835}
@@ -839,29 +851,20 @@ EXPORT_SYMBOL(snd_card_file_add);
839 */ 851 */
840int snd_card_file_remove(struct snd_card *card, struct file *file) 852int snd_card_file_remove(struct snd_card *card, struct file *file)
841{ 853{
842 struct snd_monitor_file *mfile, *pfile = NULL; 854 struct snd_monitor_file *mfile, *found = NULL;
843 int last_close = 0; 855 int last_close = 0;
844 856
845 spin_lock(&card->files_lock); 857 spin_lock(&card->files_lock);
846 mfile = card->files; 858 list_for_each_entry(mfile, &card->files_list, list) {
847 while (mfile) {
848 if (mfile->file == file) { 859 if (mfile->file == file) {
849 if (pfile) 860 list_del(&mfile->list);
850 pfile->next = mfile->next; 861 if (mfile->disconnected_f_op)
851 else 862 fops_put(mfile->disconnected_f_op);
852 card->files = mfile->next; 863 found = mfile;
853 break; 864 break;
854 } 865 }
855 pfile = mfile;
856 mfile = mfile->next;
857 }
858 if (mfile && mfile->disconnected_f_op) {
859 fops_put(mfile->disconnected_f_op);
860 spin_lock(&shutdown_lock);
861 list_del(&mfile->shutdown_list);
862 spin_unlock(&shutdown_lock);
863 } 866 }
864 if (card->files == NULL) 867 if (list_empty(&card->files_list))
865 last_close = 1; 868 last_close = 1;
866 spin_unlock(&card->files_lock); 869 spin_unlock(&card->files_lock);
867 if (last_close) { 870 if (last_close) {
@@ -869,11 +872,11 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
869 if (card->free_on_last_close) 872 if (card->free_on_last_close)
870 snd_card_do_free(card); 873 snd_card_do_free(card);
871 } 874 }
872 if (!mfile) { 875 if (!found) {
873 snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file); 876 snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
874 return -ENOENT; 877 return -ENOENT;
875 } 878 }
876 kfree(mfile); 879 kfree(found);
877 return 0; 880 return 0;
878} 881}
879 882