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