vserver 1.9.3
[linux-2.6.git] / sound / core / control.c
1 /*
2  *  Routines for driver control interface
3  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4  *
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  *
20  */
21
22 #include <sound/driver.h>
23 #include <linux/threads.h>
24 #include <linux/interrupt.h>
25 #include <linux/smp_lock.h>
26 #include <linux/slab.h>
27 #include <linux/vmalloc.h>
28 #include <linux/time.h>
29 #include <sound/core.h>
30 #include <sound/minors.h>
31 #include <sound/info.h>
32 #include <sound/control.h>
33
34 typedef struct _snd_kctl_ioctl {
35         struct list_head list;          /* list of all ioctls */
36         snd_kctl_ioctl_func_t fioctl;
37 } snd_kctl_ioctl_t;
38
39 #define snd_kctl_ioctl(n) list_entry(n, snd_kctl_ioctl_t, list)
40
41 static DECLARE_RWSEM(snd_ioctl_rwsem);
42 static LIST_HEAD(snd_control_ioctls);
43
44 static int snd_ctl_open(struct inode *inode, struct file *file)
45 {
46         int cardnum = SNDRV_MINOR_CARD(iminor(inode));
47         unsigned long flags;
48         snd_card_t *card;
49         snd_ctl_file_t *ctl;
50         int err;
51
52         card = snd_cards[cardnum];
53         if (!card) {
54                 err = -ENODEV;
55                 goto __error1;
56         }
57         err = snd_card_file_add(card, file);
58         if (err < 0) {
59                 err = -ENODEV;
60                 goto __error1;
61         }
62         if (!try_module_get(card->module)) {
63                 err = -EFAULT;
64                 goto __error2;
65         }
66         ctl = kcalloc(1, sizeof(*ctl), GFP_KERNEL);
67         if (ctl == NULL) {
68                 err = -ENOMEM;
69                 goto __error;
70         }
71         INIT_LIST_HEAD(&ctl->events);
72         init_waitqueue_head(&ctl->change_sleep);
73         spin_lock_init(&ctl->read_lock);
74         ctl->card = card;
75         ctl->pid = current->pid;
76         file->private_data = ctl;
77         write_lock_irqsave(&card->ctl_files_rwlock, flags);
78         list_add_tail(&ctl->list, &card->ctl_files);
79         write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
80         return 0;
81
82       __error:
83         module_put(card->module);
84       __error2:
85         snd_card_file_remove(card, file);
86       __error1:
87         return err;
88 }
89
90 static void snd_ctl_empty_read_queue(snd_ctl_file_t * ctl)
91 {
92         snd_kctl_event_t *cread;
93         
94         spin_lock(&ctl->read_lock);
95         while (!list_empty(&ctl->events)) {
96                 cread = snd_kctl_event(ctl->events.next);
97                 list_del(&cread->list);
98                 kfree(cread);
99         }
100         spin_unlock(&ctl->read_lock);
101 }
102
103 static int snd_ctl_release(struct inode *inode, struct file *file)
104 {
105         unsigned long flags;
106         struct list_head *list;
107         snd_card_t *card;
108         snd_ctl_file_t *ctl;
109         snd_kcontrol_t *control;
110         unsigned int idx;
111
112         ctl = file->private_data;
113         fasync_helper(-1, file, 0, &ctl->fasync);
114         file->private_data = NULL;
115         card = ctl->card;
116         write_lock_irqsave(&card->ctl_files_rwlock, flags);
117         list_del(&ctl->list);
118         write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
119         down_write(&card->controls_rwsem);
120         list_for_each(list, &card->controls) {
121                 control = snd_kcontrol(list);
122                 for (idx = 0; idx < control->count; idx++)
123                         if (control->vd[idx].owner == ctl)
124                                 control->vd[idx].owner = NULL;
125         }
126         up_write(&card->controls_rwsem);
127         snd_ctl_empty_read_queue(ctl);
128         kfree(ctl);
129         module_put(card->module);
130         snd_card_file_remove(card, file);
131         return 0;
132 }
133
134 void snd_ctl_notify(snd_card_t *card, unsigned int mask, snd_ctl_elem_id_t *id)
135 {
136         unsigned long flags;
137         struct list_head *flist;
138         snd_ctl_file_t *ctl;
139         snd_kctl_event_t *ev;
140         
141         snd_runtime_check(card != NULL && id != NULL, return);
142         read_lock(&card->ctl_files_rwlock);
143 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
144         card->mixer_oss_change_count++;
145 #endif
146         list_for_each(flist, &card->ctl_files) {
147                 struct list_head *elist;
148                 ctl = snd_ctl_file(flist);
149                 if (!ctl->subscribed)
150                         continue;
151                 spin_lock_irqsave(&ctl->read_lock, flags);
152                 list_for_each(elist, &ctl->events) {
153                         ev = snd_kctl_event(elist);
154                         if (ev->id.numid == id->numid) {
155                                 ev->mask |= mask;
156                                 goto _found;
157                         }
158                 }
159                 ev = kcalloc(1, sizeof(*ev), GFP_ATOMIC);
160                 if (ev) {
161                         ev->id = *id;
162                         ev->mask = mask;
163                         list_add_tail(&ev->list, &ctl->events);
164                 } else {
165                         snd_printk(KERN_ERR "No memory available to allocate event\n");
166                 }
167         _found:
168                 wake_up(&ctl->change_sleep);
169                 spin_unlock_irqrestore(&ctl->read_lock, flags);
170                 kill_fasync(&ctl->fasync, SIGIO, POLL_IN);
171         }
172         read_unlock(&card->ctl_files_rwlock);
173 }
174
175 /**
176  * snd_ctl_new - create a control instance from the template
177  * @control: the control template
178  * @access: the default control access
179  *
180  * Allocates a new snd_kcontrol_t instance and copies the given template 
181  * to the new instance. It does not copy volatile data (access).
182  *
183  * Returns the pointer of the new instance, or NULL on failure.
184  */
185 snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control, unsigned int access)
186 {
187         snd_kcontrol_t *kctl;
188         unsigned int idx;
189         
190         snd_runtime_check(control != NULL, return NULL);
191         snd_runtime_check(control->count > 0, return NULL);
192         kctl = kcalloc(1, sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL);
193         if (kctl == NULL)
194                 return NULL;
195         *kctl = *control;
196         for (idx = 0; idx < kctl->count; idx++)
197                 kctl->vd[idx].access = access;
198         return kctl;
199 }
200
201 /**
202  * snd_ctl_new1 - create a control instance from the template
203  * @ncontrol: the initialization record
204  * @private_data: the private data to set
205  *
206  * Allocates a new snd_kcontrol_t instance and initialize from the given 
207  * template.  When the access field of ncontrol is 0, it's assumed as
208  * READWRITE access. When the count field is 0, it's assumes as one.
209  *
210  * Returns the pointer of the newly generated instance, or NULL on failure.
211  */
212 snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * ncontrol, void *private_data)
213 {
214         snd_kcontrol_t kctl;
215         unsigned int access;
216         
217         snd_runtime_check(ncontrol != NULL, return NULL);
218         snd_assert(ncontrol->info != NULL, return NULL);
219         memset(&kctl, 0, sizeof(kctl));
220         kctl.id.iface = ncontrol->iface;
221         kctl.id.device = ncontrol->device;
222         kctl.id.subdevice = ncontrol->subdevice;
223         if (ncontrol->name)
224                 strlcpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name));
225         kctl.id.index = ncontrol->index;
226         kctl.count = ncontrol->count ? ncontrol->count : 1;
227         access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
228                  (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|SNDRV_CTL_ELEM_ACCESS_INACTIVE|
229                                       SNDRV_CTL_ELEM_ACCESS_DINDIRECT|SNDRV_CTL_ELEM_ACCESS_INDIRECT));
230         kctl.info = ncontrol->info;
231         kctl.get = ncontrol->get;
232         kctl.put = ncontrol->put;
233         kctl.private_value = ncontrol->private_value;
234         kctl.private_data = private_data;
235         return snd_ctl_new(&kctl, access);
236 }
237
238 /**
239  * snd_ctl_free_one - release the control instance
240  * @kcontrol: the control instance
241  *
242  * Releases the control instance created via snd_ctl_new()
243  * or snd_ctl_new1().
244  * Don't call this after the control was added to the card.
245  */
246 void snd_ctl_free_one(snd_kcontrol_t * kcontrol)
247 {
248         if (kcontrol) {
249                 if (kcontrol->private_free)
250                         kcontrol->private_free(kcontrol);
251                 kfree(kcontrol);
252         }
253 }
254
255 static unsigned int snd_ctl_hole_check(snd_card_t * card,
256                                        unsigned int count)
257 {
258         struct list_head *list;
259         snd_kcontrol_t *kctl;
260
261         list_for_each(list, &card->controls) {
262                 kctl = snd_kcontrol(list);
263                 if ((kctl->id.numid <= card->last_numid &&
264                      kctl->id.numid + kctl->count > card->last_numid) ||
265                     (kctl->id.numid <= card->last_numid + count - 1 &&
266                      kctl->id.numid + kctl->count > card->last_numid + count - 1))
267                         return card->last_numid = kctl->id.numid + kctl->count - 1;
268         }
269         return card->last_numid;
270 }
271
272 static int snd_ctl_find_hole(snd_card_t * card, unsigned int count)
273 {
274         unsigned int last_numid, iter = 100000;
275
276         last_numid = card->last_numid;
277         while (last_numid != snd_ctl_hole_check(card, count)) {
278                 if (--iter == 0) {
279                         /* this situation is very unlikely */
280                         snd_printk(KERN_ERR "unable to allocate new control numid\n");
281                         return -ENOMEM;
282                 }
283                 last_numid = card->last_numid;
284         }
285         return 0;
286 }
287
288 /**
289  * snd_ctl_add - add the control instance to the card
290  * @card: the card instance
291  * @kcontrol: the control instance to add
292  *
293  * Adds the control instance created via snd_ctl_new() or
294  * snd_ctl_new1() to the given card. Assigns also an unique
295  * numid used for fast search.
296  *
297  * Returns zero if successful, or a negative error code on failure.
298  *
299  * It frees automatically the control which cannot be added.
300  */
301 int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol)
302 {
303         snd_ctl_elem_id_t id;
304         unsigned int idx;
305
306         snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
307         snd_assert(kcontrol->info != NULL, return -EINVAL);
308         id = kcontrol->id;
309         down_write(&card->controls_rwsem);
310         if (snd_ctl_find_id(card, &id)) {
311                 up_write(&card->controls_rwsem);
312                 snd_ctl_free_one(kcontrol);
313                 snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n",
314                                         id.iface,
315                                         id.device,
316                                         id.subdevice,
317                                         id.name,
318                                         id.index);
319                 return -EBUSY;
320         }
321         if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
322                 up_write(&card->controls_rwsem);
323                 snd_ctl_free_one(kcontrol);
324                 return -ENOMEM;
325         }
326         list_add_tail(&kcontrol->list, &card->controls);
327         card->controls_count += kcontrol->count;
328         kcontrol->id.numid = card->last_numid + 1;
329         card->last_numid += kcontrol->count;
330         up_write(&card->controls_rwsem);
331         for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
332                 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
333         return 0;
334 }
335
336 /**
337  * snd_ctl_remove - remove the control from the card and release it
338  * @card: the card instance
339  * @kcontrol: the control instance to remove
340  *
341  * Removes the control from the card and then releases the instance.
342  * You don't need to call snd_ctl_free_one(). You must be in
343  * the write lock - down_write(&card->controls_rwsem).
344  * 
345  * Returns 0 if successful, or a negative error code on failure.
346  */
347 int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol)
348 {
349         snd_ctl_elem_id_t id;
350         unsigned int idx;
351
352         snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
353         list_del(&kcontrol->list);
354         card->controls_count -= kcontrol->count;
355         id = kcontrol->id;
356         for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
357                 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_REMOVE, &id);
358         snd_ctl_free_one(kcontrol);
359         return 0;
360 }
361
362 /**
363  * snd_ctl_remove_id - remove the control of the given id and release it
364  * @card: the card instance
365  * @id: the control id to remove
366  *
367  * Finds the control instance with the given id, removes it from the
368  * card list and releases it.
369  * 
370  * Returns 0 if successful, or a negative error code on failure.
371  */
372 int snd_ctl_remove_id(snd_card_t * card, snd_ctl_elem_id_t *id)
373 {
374         snd_kcontrol_t *kctl;
375         int ret;
376
377         down_write(&card->controls_rwsem);
378         kctl = snd_ctl_find_id(card, id);
379         if (kctl == NULL) {
380                 up_write(&card->controls_rwsem);
381                 return -ENOENT;
382         }
383         ret = snd_ctl_remove(card, kctl);
384         up_write(&card->controls_rwsem);
385         return ret;
386 }
387
388 /**
389  * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it
390  * @file: active control handle
391  * @id: the control id to remove
392  *
393  * Finds the control instance with the given id, removes it from the
394  * card list and releases it.
395  * 
396  * Returns 0 if successful, or a negative error code on failure.
397  */
398 static int snd_ctl_remove_unlocked_id(snd_ctl_file_t * file, snd_ctl_elem_id_t *id)
399 {
400         snd_card_t *card = file->card;
401         snd_kcontrol_t *kctl;
402         int idx, ret;
403
404         down_write(&card->controls_rwsem);
405         kctl = snd_ctl_find_id(card, id);
406         if (kctl == NULL) {
407                 up_write(&card->controls_rwsem);
408                 return -ENOENT;
409         }
410         for (idx = 0; idx < kctl->count; idx++)
411                 if (kctl->vd[idx].owner != NULL && kctl->vd[idx].owner != file) {
412                         up_write(&card->controls_rwsem);
413                         return -EBUSY;
414                 }
415         ret = snd_ctl_remove(card, kctl);
416         up_write(&card->controls_rwsem);
417         return ret;
418 }
419
420 /**
421  * snd_ctl_rename_id - replace the id of a control on the card
422  * @card: the card instance
423  * @src_id: the old id
424  * @dst_id: the new id
425  *
426  * Finds the control with the old id from the card, and replaces the
427  * id with the new one.
428  *
429  * Returns zero if successful, or a negative error code on failure.
430  */
431 int snd_ctl_rename_id(snd_card_t * card, snd_ctl_elem_id_t *src_id, snd_ctl_elem_id_t *dst_id)
432 {
433         snd_kcontrol_t *kctl;
434
435         down_write(&card->controls_rwsem);
436         kctl = snd_ctl_find_id(card, src_id);
437         if (kctl == NULL) {
438                 up_write(&card->controls_rwsem);
439                 return -ENOENT;
440         }
441         kctl->id = *dst_id;
442         kctl->id.numid = card->last_numid + 1;
443         card->last_numid += kctl->count;
444         up_write(&card->controls_rwsem);
445         return 0;
446 }
447
448 /**
449  * snd_ctl_find_numid - find the control instance with the given number-id
450  * @card: the card instance
451  * @numid: the number-id to search
452  *
453  * Finds the control instance with the given number-id from the card.
454  *
455  * Returns the pointer of the instance if found, or NULL if not.
456  *
457  * The caller must down card->controls_rwsem before calling this function
458  * (if the race condition can happen).
459  */
460 snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid)
461 {
462         struct list_head *list;
463         snd_kcontrol_t *kctl;
464
465         snd_runtime_check(card != NULL && numid != 0, return NULL);
466         list_for_each(list, &card->controls) {
467                 kctl = snd_kcontrol(list);
468                 if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
469                         return kctl;
470         }
471         return NULL;
472 }
473
474 /**
475  * snd_ctl_find_id - find the control instance with the given id
476  * @card: the card instance
477  * @id: the id to search
478  *
479  * Finds the control instance with the given id from the card.
480  *
481  * Returns the pointer of the instance if found, or NULL if not.
482  *
483  * The caller must down card->controls_rwsem before calling this function
484  * (if the race condition can happen).
485  */
486 snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
487 {
488         struct list_head *list;
489         snd_kcontrol_t *kctl;
490
491         snd_runtime_check(card != NULL && id != NULL, return NULL);
492         if (id->numid != 0)
493                 return snd_ctl_find_numid(card, id->numid);
494         list_for_each(list, &card->controls) {
495                 kctl = snd_kcontrol(list);
496                 if (kctl->id.iface != id->iface)
497                         continue;
498                 if (kctl->id.device != id->device)
499                         continue;
500                 if (kctl->id.subdevice != id->subdevice)
501                         continue;
502                 if (strncmp(kctl->id.name, id->name, sizeof(kctl->id.name)))
503                         continue;
504                 if (kctl->id.index > id->index)
505                         continue;
506                 if (kctl->id.index + kctl->count <= id->index)
507                         continue;
508                 return kctl;
509         }
510         return NULL;
511 }
512
513 static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl,
514                              unsigned int cmd, void __user *arg)
515 {
516         snd_ctl_card_info_t info;
517
518         memset(&info, 0, sizeof(info));
519         down_read(&snd_ioctl_rwsem);
520         info.card = card->number;
521         strlcpy(info.id, card->id, sizeof(info.id));
522         strlcpy(info.driver, card->driver, sizeof(info.driver));
523         strlcpy(info.name, card->shortname, sizeof(info.name));
524         strlcpy(info.longname, card->longname, sizeof(info.longname));
525         strlcpy(info.mixername, card->mixername, sizeof(info.mixername));
526         strlcpy(info.components, card->components, sizeof(info.components));
527         up_read(&snd_ioctl_rwsem);
528         if (copy_to_user(arg, &info, sizeof(snd_ctl_card_info_t)))
529                 return -EFAULT;
530         return 0;
531 }
532
533 static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t __user *_list)
534 {
535         struct list_head *plist;
536         snd_ctl_elem_list_t list;
537         snd_kcontrol_t *kctl;
538         snd_ctl_elem_id_t *dst, *id;
539         unsigned int offset, space, first, jidx;
540         
541         if (copy_from_user(&list, _list, sizeof(list)))
542                 return -EFAULT;
543         offset = list.offset;
544         space = list.space;
545         first = 0;
546         /* try limit maximum space */
547         if (space > 16384)
548                 return -ENOMEM;
549         if (space > 0) {
550                 /* allocate temporary buffer for atomic operation */
551                 dst = vmalloc(space * sizeof(snd_ctl_elem_id_t));
552                 if (dst == NULL)
553                         return -ENOMEM;
554                 down_read(&card->controls_rwsem);
555                 list.count = card->controls_count;
556                 plist = card->controls.next;
557                 while (plist != &card->controls) {
558                         if (offset == 0)
559                                 break;
560                         kctl = snd_kcontrol(plist);
561                         if (offset < kctl->count)
562                                 break;
563                         offset -= kctl->count;
564                         plist = plist->next;
565                 }
566                 list.used = 0;
567                 id = dst;
568                 while (space > 0 && plist != &card->controls) {
569                         kctl = snd_kcontrol(plist);
570                         for (jidx = offset; space > 0 && jidx < kctl->count; jidx++) {
571                                 snd_ctl_build_ioff(id, kctl, jidx);
572                                 id++;
573                                 space--;
574                                 list.used++;
575                         }
576                         plist = plist->next;
577                         offset = 0;
578                 }
579                 up_read(&card->controls_rwsem);
580                 if (list.used > 0 && copy_to_user(list.pids, dst, list.used * sizeof(snd_ctl_elem_id_t))) {
581                         vfree(dst);
582                         return -EFAULT;
583                 }
584                 vfree(dst);
585         } else {
586                 down_read(&card->controls_rwsem);
587                 list.count = card->controls_count;
588                 up_read(&card->controls_rwsem);
589         }
590         if (copy_to_user(_list, &list, sizeof(list)))
591                 return -EFAULT;
592         return 0;
593 }
594
595 static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t __user *_info)
596 {
597         snd_card_t *card = ctl->card;
598         snd_ctl_elem_info_t info;
599         snd_kcontrol_t *kctl;
600         snd_kcontrol_volatile_t *vd;
601         unsigned int index_offset;
602         int result;
603         
604         if (copy_from_user(&info, _info, sizeof(info)))
605                 return -EFAULT;
606         down_read(&card->controls_rwsem);
607         kctl = snd_ctl_find_id(card, &info.id);
608         if (kctl == NULL) {
609                 up_read(&card->controls_rwsem);
610                 return -ENOENT;
611         }
612 #ifdef CONFIG_SND_DEBUG
613         info.access = 0;
614 #endif
615         result = kctl->info(kctl, &info);
616         if (result >= 0) {
617                 snd_assert(info.access == 0, );
618                 index_offset = snd_ctl_get_ioff(kctl, &info.id);
619                 vd = &kctl->vd[index_offset];
620                 snd_ctl_build_ioff(&info.id, kctl, index_offset);
621                 info.access = vd->access;
622                 if (vd->owner) {
623                         info.access |= SNDRV_CTL_ELEM_ACCESS_LOCK;
624                         if (vd->owner == ctl)
625                                 info.access |= SNDRV_CTL_ELEM_ACCESS_OWNER;
626                         info.owner = vd->owner_pid;
627                 } else {
628                         info.owner = -1;
629                 }
630         }
631         up_read(&card->controls_rwsem);
632         if (result >= 0)
633                 if (copy_to_user(_info, &info, sizeof(info)))
634                         return -EFAULT;
635         return result;
636 }
637
638 static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t __user *_control)
639 {
640         snd_ctl_elem_value_t *control;
641         snd_kcontrol_t *kctl;
642         snd_kcontrol_volatile_t *vd;
643         unsigned int index_offset;
644         int result, indirect;
645         
646         control = kmalloc(sizeof(*control), GFP_KERNEL);
647         if (control == NULL)
648                 return -ENOMEM; 
649         if (copy_from_user(control, _control, sizeof(*control)))
650                 return -EFAULT;
651         down_read(&card->controls_rwsem);
652         kctl = snd_ctl_find_id(card, &control->id);
653         if (kctl == NULL) {
654                 result = -ENOENT;
655         } else {
656                 index_offset = snd_ctl_get_ioff(kctl, &control->id);
657                 vd = &kctl->vd[index_offset];
658                 indirect = vd->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0;
659                 if (control->indirect != indirect) {
660                         result = -EACCES;
661                 } else {
662                         if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get != NULL) {
663                                 snd_ctl_build_ioff(&control->id, kctl, index_offset);
664                                 result = kctl->get(kctl, control);
665                         } else {
666                                 result = -EPERM;
667                         }
668                 }
669         }
670         up_read(&card->controls_rwsem);
671         if (result >= 0)
672                 if (copy_to_user(_control, control, sizeof(*control)))
673                         return -EFAULT;
674         kfree(control);
675         return result;
676 }
677
678 static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t __user *_control)
679 {
680         snd_card_t *card = file->card;
681         snd_ctl_elem_value_t *control;
682         snd_kcontrol_t *kctl;
683         snd_kcontrol_volatile_t *vd;
684         unsigned int index_offset;
685         int result, indirect;
686
687         control = kmalloc(sizeof(*control), GFP_KERNEL);
688         if (control == NULL)
689                 return -ENOMEM; 
690         if (copy_from_user(control, _control, sizeof(*control)))
691                 return -EFAULT;
692         down_read(&card->controls_rwsem);
693         kctl = snd_ctl_find_id(card, &control->id);
694         if (kctl == NULL) {
695                 result = -ENOENT;
696         } else {
697                 index_offset = snd_ctl_get_ioff(kctl, &control->id);
698                 vd = &kctl->vd[index_offset];
699                 indirect = vd->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0;
700                 if (control->indirect != indirect) {
701                         result = -EACCES;
702                 } else {
703                         if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
704                             kctl->put == NULL ||
705                             (vd->owner != NULL && vd->owner != file)) {
706                                 result = -EPERM;
707                         } else {
708                                 snd_ctl_build_ioff(&control->id, kctl, index_offset);
709                                 result = kctl->put(kctl, control);
710                         }
711                         if (result > 0) {
712                                 up_read(&card->controls_rwsem);
713                                 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &control->id);
714                                 result = 0;
715                                 goto __unlocked;
716                         }
717                 }
718         }
719         up_read(&card->controls_rwsem);
720       __unlocked:
721         if (result >= 0)
722                 if (copy_to_user(_control, control, sizeof(*control)))
723                         return -EFAULT;
724         kfree(control);
725         return result;
726 }
727
728 static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
729 {
730         snd_card_t *card = file->card;
731         snd_ctl_elem_id_t id;
732         snd_kcontrol_t *kctl;
733         snd_kcontrol_volatile_t *vd;
734         int result;
735         
736         if (copy_from_user(&id, _id, sizeof(id)))
737                 return -EFAULT;
738         down_write(&card->controls_rwsem);
739         kctl = snd_ctl_find_id(card, &id);
740         if (kctl == NULL) {
741                 result = -ENOENT;
742         } else {
743                 vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
744                 if (vd->owner != NULL)
745                         result = -EBUSY;
746                 else {
747                         vd->owner = file;
748                         vd->owner_pid = current->pid;
749                         result = 0;
750                 }
751         }
752         up_write(&card->controls_rwsem);
753         return result;
754 }
755
756 static int snd_ctl_elem_unlock(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
757 {
758         snd_card_t *card = file->card;
759         snd_ctl_elem_id_t id;
760         snd_kcontrol_t *kctl;
761         snd_kcontrol_volatile_t *vd;
762         int result;
763         
764         if (copy_from_user(&id, _id, sizeof(id)))
765                 return -EFAULT;
766         down_write(&card->controls_rwsem);
767         kctl = snd_ctl_find_id(card, &id);
768         if (kctl == NULL) {
769                 result = -ENOENT;
770         } else {
771                 vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
772                 if (vd->owner == NULL)
773                         result = -EINVAL;
774                 else if (vd->owner != file)
775                         result = -EPERM;
776                 else {
777                         vd->owner = NULL;
778                         vd->owner_pid = 0;
779                         result = 0;
780                 }
781         }
782         up_write(&card->controls_rwsem);
783         return result;
784 }
785
786 struct user_element {
787         enum sndrv_ctl_elem_type type;  /* element type */
788         unsigned int elem_count;        /* count of elements */
789         union {
790                 struct {
791                         unsigned int items;
792                 } enumerated;
793         } u;
794         void *elem_data;                /* element data */
795         unsigned long elem_data_size;   /* size of element data in bytes */
796         void *priv_data;                /* private data (like strings for enumerated type) */
797         unsigned long priv_data_size;   /* size of private data in bytes */
798         unsigned short dimen_count;     /* count of dimensions */
799         unsigned short dimen[0];        /* array of dimensions */
800 };
801
802 static int snd_ctl_elem_user_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
803 {
804         struct user_element *ue = kcontrol->private_data;
805
806         uinfo->type = ue->type;
807         uinfo->count = ue->elem_count;
808         if (ue->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
809                 uinfo->value.enumerated.items = ue->u.enumerated.items;
810                 if (uinfo->value.enumerated.item >= ue->u.enumerated.items)
811                         uinfo->value.enumerated.item = 0;
812                 strlcpy(uinfo->value.enumerated.name,
813                         (char *)ue->priv_data + uinfo->value.enumerated.item * 64,
814                         64);
815         }
816         return 0;
817 }
818
819 static int snd_ctl_elem_user_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
820 {
821         struct user_element *ue = kcontrol->private_data;
822
823         memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size);
824         return 0;
825 }
826
827 static int snd_ctl_elem_user_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
828 {
829         int change;
830         struct user_element *ue = kcontrol->private_data;
831         
832         change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size);
833         memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
834         return !!change;
835 }
836
837 static void snd_ctl_elem_user_free(snd_kcontrol_t * kcontrol)
838 {
839         kfree(kcontrol->private_data);
840 }
841
842 static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t __user *_info, int replace)
843 {
844         snd_card_t *card = file->card;
845         snd_ctl_elem_info_t info;
846         snd_kcontrol_t kctl, *_kctl;
847         unsigned int access;
848         long private_size, dimen_size, extra_size;
849         struct user_element *ue;
850         int idx, err;
851         
852         if (copy_from_user(&info, _info, sizeof(info)))
853                 return -EFAULT;
854         if (info.count > 1024)
855                 return -EINVAL;
856         access = info.access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
857                  (info.access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|SNDRV_CTL_ELEM_ACCESS_INACTIVE|
858                                  SNDRV_CTL_ELEM_ACCESS_DINDIRECT|SNDRV_CTL_ELEM_ACCESS_INDIRECT));
859         if (access & (SNDRV_CTL_ELEM_ACCESS_DINDIRECT | SNDRV_CTL_ELEM_ACCESS_INDIRECT))
860                 return -EINVAL;
861         info.id.numid = 0;
862         memset(&kctl, 0, sizeof(kctl));
863         down_write(&card->controls_rwsem);
864         if (!!((_kctl = snd_ctl_find_id(card, &info.id)) != NULL) ^ replace) {
865                 up_write(&card->controls_rwsem);
866                 return !replace ? -EBUSY : -ENOENT;
867         }
868         if (replace) {
869                 err = snd_ctl_remove(card, _kctl);
870                 if (err < 0) {
871                         up_write(&card->controls_rwsem);
872                         return err;
873                 }
874         }
875         up_write(&card->controls_rwsem);
876         memcpy(&kctl.id, &info.id, sizeof(info.id));
877         kctl.count = info.owner ? info.owner : 1;
878         access |= SNDRV_CTL_ELEM_ACCESS_USER;
879         kctl.info = snd_ctl_elem_user_info;
880         if (access & SNDRV_CTL_ELEM_ACCESS_READ)
881                 kctl.get = snd_ctl_elem_user_get;
882         if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
883                 kctl.put = snd_ctl_elem_user_put;
884         extra_size = 0;
885         switch (info.type) {
886         case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
887                 private_size = sizeof(char);
888                 if (info.count > 128)
889                         return -EINVAL;
890                 break;
891         case SNDRV_CTL_ELEM_TYPE_INTEGER:
892                 private_size = sizeof(long);
893                 if (info.count > 128)
894                         return -EINVAL;
895                 break;
896         case SNDRV_CTL_ELEM_TYPE_INTEGER64:
897                 private_size = sizeof(long long);
898                 if (info.count > 64)
899                         return -EINVAL;
900                 break;
901         case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
902                 private_size = sizeof(unsigned int);
903                 if (info.count > 128)
904                         return -EINVAL;
905                 if (info.value.enumerated.items > 1024)
906                         return -EINVAL;
907                 extra_size = info.value.enumerated.items * 64;
908                 break;
909         case SNDRV_CTL_ELEM_TYPE_BYTES:
910                 private_size = sizeof(unsigned char);
911                 if (info.count > 512)
912                         return -EINVAL;
913                 break;
914         case SNDRV_CTL_ELEM_TYPE_IEC958:
915                 private_size = sizeof(struct sndrv_aes_iec958);
916                 if (info.count != 1)
917                         return -EINVAL;
918                 break;
919         default:
920                 return -EINVAL;
921         }
922         private_size *= info.count;
923         if (private_size > 1024 * 1024)
924                 return -EINVAL;
925         dimen_size = 0;
926         if (!(info.access & SNDRV_CTL_ELEM_ACCESS_DINDIRECT))
927                 for (idx = 0; idx < 4 && info.dimen.d[idx]; idx++)
928                         dimen_size += sizeof(unsigned short);
929         ue = kcalloc(1, sizeof(struct user_element) + dimen_size + private_size + extra_size, GFP_KERNEL);
930         if (ue == NULL)
931                 return -ENOMEM;
932         ue->type = info.type;
933         ue->elem_count = info.count;
934         if (!(info.access & SNDRV_CTL_ELEM_ACCESS_DINDIRECT)) {
935                 for (idx = 0; idx < 4 && info.dimen.d[idx]; idx++)
936                         ue->dimen[idx] = info.dimen.d[idx];
937                 ue->dimen_count = dimen_size / sizeof(unsigned short);
938         }
939         ue->elem_data = (char *)ue + sizeof(ue) + dimen_size;
940         ue->elem_data_size = private_size;
941         if (extra_size) {
942                 ue->priv_data = (char *)ue + sizeof(ue) + dimen_size + private_size;
943                 ue->priv_data_size = extra_size;
944                 if (ue->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
945                         if (copy_from_user(ue->priv_data, *(char **)info.value.enumerated.name, extra_size))
946                                 return -EFAULT;
947                         ue->u.enumerated.items = info.value.enumerated.items;
948                 }
949         }
950         kctl.private_free = snd_ctl_elem_user_free;
951         _kctl = snd_ctl_new(&kctl, access);
952         if (_kctl == NULL) {
953                 kfree(_kctl->private_data);
954                 return -ENOMEM;
955         }
956         _kctl->private_data = ue;
957         for (idx = 0; idx < _kctl->count; idx++)
958                 _kctl->vd[idx].owner = file;
959         err = snd_ctl_add(card, _kctl);
960         if (err < 0) {
961                 snd_ctl_free_one(_kctl);
962                 return err;
963         }
964         return 0;
965 }
966
967 static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
968 {
969         snd_ctl_elem_id_t id;
970
971         if (copy_from_user(&id, _id, sizeof(id)))
972                 return -EFAULT;
973         return snd_ctl_remove_unlocked_id(file, &id);
974 }
975
976 static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int __user *ptr)
977 {
978         int subscribe;
979         if (get_user(subscribe, ptr))
980                 return -EFAULT;
981         if (subscribe < 0) {
982                 subscribe = file->subscribed;
983                 if (put_user(subscribe, ptr))
984                         return -EFAULT;
985                 return 0;
986         }
987         if (subscribe) {
988                 file->subscribed = 1;
989                 return 0;
990         } else if (file->subscribed) {
991                 snd_ctl_empty_read_queue(file);
992                 file->subscribed = 0;
993         }
994         return 0;
995 }
996
997 #ifdef CONFIG_PM
998 /*
999  * change the power state
1000  */
1001 static int snd_ctl_set_power_state(snd_card_t *card, unsigned int power_state)
1002 {
1003         switch (power_state) {
1004         case SNDRV_CTL_POWER_D0:
1005         case SNDRV_CTL_POWER_D1:
1006         case SNDRV_CTL_POWER_D2:
1007                 if (card->power_state != power_state)
1008                         /* FIXME: pass the correct state value */
1009                         card->pm_resume(card, 0);
1010                 break;
1011         case SNDRV_CTL_POWER_D3hot:
1012         case SNDRV_CTL_POWER_D3cold:
1013                 if (card->power_state != power_state)
1014                         /* FIXME: pass the correct state value */
1015                         card->pm_suspend(card, 0);
1016                 break;
1017         default:
1018                 return -EINVAL;
1019         }
1020         return 0;
1021 }
1022 #endif
1023
1024 static inline int _snd_ctl_ioctl(struct inode *inode, struct file *file,
1025                                  unsigned int cmd, unsigned long arg)
1026 {
1027         snd_ctl_file_t *ctl;
1028         snd_card_t *card;
1029         struct list_head *list;
1030         snd_kctl_ioctl_t *p;
1031         void __user *argp = (void __user *)arg;
1032         int __user *ip = argp;
1033         int err;
1034
1035         ctl = file->private_data;
1036         card = ctl->card;
1037         snd_assert(card != NULL, return -ENXIO);
1038         switch (cmd) {
1039         case SNDRV_CTL_IOCTL_PVERSION:
1040                 return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0;
1041         case SNDRV_CTL_IOCTL_CARD_INFO:
1042                 return snd_ctl_card_info(card, ctl, cmd, argp);
1043         case SNDRV_CTL_IOCTL_ELEM_LIST:
1044                 return snd_ctl_elem_list(ctl->card, argp);
1045         case SNDRV_CTL_IOCTL_ELEM_INFO:
1046                 return snd_ctl_elem_info(ctl, argp);
1047         case SNDRV_CTL_IOCTL_ELEM_READ:
1048                 return snd_ctl_elem_read(ctl->card, argp);
1049         case SNDRV_CTL_IOCTL_ELEM_WRITE:
1050                 return snd_ctl_elem_write(ctl, argp);
1051         case SNDRV_CTL_IOCTL_ELEM_LOCK:
1052                 return snd_ctl_elem_lock(ctl, argp);
1053         case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
1054                 return snd_ctl_elem_unlock(ctl, argp);
1055         case SNDRV_CTL_IOCTL_ELEM_ADD:
1056                 return snd_ctl_elem_add(ctl, argp, 0);
1057         case SNDRV_CTL_IOCTL_ELEM_REPLACE:
1058                 return snd_ctl_elem_add(ctl, argp, 1);
1059         case SNDRV_CTL_IOCTL_ELEM_REMOVE:
1060                 return snd_ctl_elem_remove(ctl, argp);
1061         case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
1062                 return snd_ctl_subscribe_events(ctl, ip);
1063         case SNDRV_CTL_IOCTL_POWER:
1064                 if (get_user(err, ip))
1065                         return -EFAULT;
1066                 if (!capable(CAP_SYS_ADMIN))
1067                         return -EPERM;
1068 #ifdef CONFIG_PM
1069                 if (card->pm_suspend && card->pm_resume) {
1070                         snd_power_lock(card);
1071                         err = snd_ctl_set_power_state(card, err);
1072                         snd_power_unlock(card);
1073                 } else
1074 #endif
1075                         err = -ENOPROTOOPT;
1076                 return err;
1077         case SNDRV_CTL_IOCTL_POWER_STATE:
1078 #ifdef CONFIG_PM
1079                 return put_user(card->power_state, ip) ? -EFAULT : 0;
1080 #else
1081                 return put_user(SNDRV_CTL_POWER_D0, ip) ? -EFAULT : 0;
1082 #endif
1083         }
1084         down_read(&snd_ioctl_rwsem);
1085         list_for_each(list, &snd_control_ioctls) {
1086                 p = list_entry(list, snd_kctl_ioctl_t, list);
1087                 err = p->fioctl(card, ctl, cmd, arg);
1088                 if (err != -ENOIOCTLCMD) {
1089                         up_read(&snd_ioctl_rwsem);
1090                         return err;
1091                 }
1092         }
1093         up_read(&snd_ioctl_rwsem);
1094         snd_printd("unknown ioctl = 0x%x\n", cmd);
1095         return -ENOTTY;
1096 }
1097
1098 /* FIXME: need to unlock BKL to allow preemption */
1099 static int snd_ctl_ioctl(struct inode *inode, struct file *file,
1100                          unsigned int cmd, unsigned long arg)
1101 {
1102         int err;
1103         unlock_kernel();
1104         err = _snd_ctl_ioctl(inode, file, cmd, arg);
1105         lock_kernel();
1106         return err;
1107 }
1108
1109 static ssize_t snd_ctl_read(struct file *file, char __user *buffer, size_t count, loff_t * offset)
1110 {
1111         snd_ctl_file_t *ctl;
1112         int err = 0;
1113         ssize_t result = 0;
1114
1115         ctl = file->private_data;
1116         snd_assert(ctl != NULL && ctl->card != NULL, return -ENXIO);
1117         if (!ctl->subscribed)
1118                 return -EBADFD;
1119         if (count < sizeof(snd_ctl_event_t))
1120                 return -EINVAL;
1121         spin_lock_irq(&ctl->read_lock);
1122         while (count >= sizeof(snd_ctl_event_t)) {
1123                 snd_ctl_event_t ev;
1124                 snd_kctl_event_t *kev;
1125                 while (list_empty(&ctl->events)) {
1126                         wait_queue_t wait;
1127                         if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
1128                                 err = -EAGAIN;
1129                                 goto __end_lock;
1130                         }
1131                         init_waitqueue_entry(&wait, current);
1132                         add_wait_queue(&ctl->change_sleep, &wait);
1133                         set_current_state(TASK_INTERRUPTIBLE);
1134                         spin_unlock_irq(&ctl->read_lock);
1135                         schedule();
1136                         remove_wait_queue(&ctl->change_sleep, &wait);
1137                         if (signal_pending(current))
1138                                 return result > 0 ? result : -ERESTARTSYS;
1139                         spin_lock_irq(&ctl->read_lock);
1140                 }
1141                 kev = snd_kctl_event(ctl->events.next);
1142                 ev.type = SNDRV_CTL_EVENT_ELEM;
1143                 ev.data.elem.mask = kev->mask;
1144                 ev.data.elem.id = kev->id;
1145                 list_del(&kev->list);
1146                 spin_unlock_irq(&ctl->read_lock);
1147                 kfree(kev);
1148                 if (copy_to_user(buffer, &ev, sizeof(snd_ctl_event_t))) {
1149                         err = -EFAULT;
1150                         goto __end;
1151                 }
1152                 spin_lock_irq(&ctl->read_lock);
1153                 buffer += sizeof(snd_ctl_event_t);
1154                 count -= sizeof(snd_ctl_event_t);
1155                 result += sizeof(snd_ctl_event_t);
1156         }
1157       __end_lock:
1158         spin_unlock_irq(&ctl->read_lock);
1159       __end:
1160         return result > 0 ? result : err;
1161 }
1162
1163 static unsigned int snd_ctl_poll(struct file *file, poll_table * wait)
1164 {
1165         unsigned int mask;
1166         snd_ctl_file_t *ctl;
1167
1168         ctl = file->private_data;
1169         if (!ctl->subscribed)
1170                 return 0;
1171         poll_wait(file, &ctl->change_sleep, wait);
1172
1173         mask = 0;
1174         if (!list_empty(&ctl->events))
1175                 mask |= POLLIN | POLLRDNORM;
1176
1177         return mask;
1178 }
1179
1180 /*
1181  * register the device-specific control-ioctls.
1182  * called from each device manager like pcm.c, hwdep.c, etc.
1183  */
1184 int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
1185 {
1186         snd_kctl_ioctl_t *pn;
1187
1188         pn = kcalloc(1, sizeof(snd_kctl_ioctl_t), GFP_KERNEL);
1189         if (pn == NULL)
1190                 return -ENOMEM;
1191         pn->fioctl = fcn;
1192         down_write(&snd_ioctl_rwsem);
1193         list_add_tail(&pn->list, &snd_control_ioctls);
1194         up_write(&snd_ioctl_rwsem);
1195         return 0;
1196 }
1197
1198 /*
1199  * de-register the device-specific control-ioctls.
1200  */
1201 int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
1202 {
1203         struct list_head *list;
1204         snd_kctl_ioctl_t *p;
1205
1206         snd_runtime_check(fcn != NULL, return -EINVAL);
1207         down_write(&snd_ioctl_rwsem);
1208         list_for_each(list, &snd_control_ioctls) {
1209                 p = list_entry(list, snd_kctl_ioctl_t, list);
1210                 if (p->fioctl == fcn) {
1211                         list_del(&p->list);
1212                         up_write(&snd_ioctl_rwsem);
1213                         kfree(p);
1214                         return 0;
1215                 }
1216         }
1217         up_write(&snd_ioctl_rwsem);
1218         snd_BUG();
1219         return -EINVAL;
1220 }
1221
1222 static int snd_ctl_fasync(int fd, struct file * file, int on)
1223 {
1224         snd_ctl_file_t *ctl;
1225         int err;
1226         ctl = file->private_data;
1227         err = fasync_helper(fd, file, on, &ctl->fasync);
1228         if (err < 0)
1229                 return err;
1230         return 0;
1231 }
1232
1233 /*
1234  *  INIT PART
1235  */
1236
1237 static struct file_operations snd_ctl_f_ops =
1238 {
1239         .owner =        THIS_MODULE,
1240         .read =         snd_ctl_read,
1241         .open =         snd_ctl_open,
1242         .release =      snd_ctl_release,
1243         .poll =         snd_ctl_poll,
1244         .ioctl =        snd_ctl_ioctl,
1245         .fasync =       snd_ctl_fasync,
1246 };
1247
1248 static snd_minor_t snd_ctl_reg =
1249 {
1250         .comment =      "ctl",
1251         .f_ops =        &snd_ctl_f_ops,
1252 };
1253
1254 /*
1255  * registration of the control device:
1256  * called from init.c
1257  */
1258 int snd_ctl_register(snd_card_t *card)
1259 {
1260         int err, cardnum;
1261         char name[16];
1262
1263         snd_assert(card != NULL, return -ENXIO);
1264         cardnum = card->number;
1265         snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
1266         sprintf(name, "controlC%i", cardnum);
1267         if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL,
1268                                         card, 0, &snd_ctl_reg, name)) < 0)
1269                 return err;
1270         return 0;
1271 }
1272
1273 /*
1274  * disconnection of the control device:
1275  * called from init.c
1276  */
1277 int snd_ctl_disconnect(snd_card_t *card)
1278 {
1279         struct list_head *flist;
1280         snd_ctl_file_t *ctl;
1281
1282         down_read(&card->controls_rwsem);
1283         list_for_each(flist, &card->ctl_files) {
1284                 ctl = snd_ctl_file(flist);
1285                 wake_up(&ctl->change_sleep);
1286                 kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
1287         }
1288         up_read(&card->controls_rwsem);
1289         return 0;
1290 }
1291
1292 /*
1293  * de-registration of the control device:
1294  * called from init.c
1295  */
1296 int snd_ctl_unregister(snd_card_t *card)
1297 {
1298         int err, cardnum;
1299         snd_kcontrol_t *control;
1300
1301         snd_assert(card != NULL, return -ENXIO);
1302         cardnum = card->number;
1303         snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
1304         if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL, card, 0)) < 0)
1305                 return err;
1306         down_write(&card->controls_rwsem);
1307         while (!list_empty(&card->controls)) {
1308                 control = snd_kcontrol(card->controls.next);
1309                 snd_ctl_remove(card, control);
1310         }
1311         up_write(&card->controls_rwsem);
1312         return 0;
1313 }