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