commented early_printk patch because of rejects.
[linux-flexiantxendom0-3.2.10.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(minor(inode->i_rdev));
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 /**
257  * snd_ctl_add - add the control instance to the card
258  * @card: the card instance
259  * @kcontrol: the control instance to add
260  *
261  * Adds the control instance created via snd_ctl_new() or
262  * snd_ctl_new1() to the given card.
263  *
264  * Returns zero if successful, or a negative error code on failure.
265  */
266 int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol)
267 {
268         snd_ctl_elem_id_t id;
269         unsigned int idx;
270
271         snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
272         snd_assert(kcontrol->info != NULL, return -EINVAL);
273         down_write(&card->controls_rwsem);
274         list_add_tail(&kcontrol->list, &card->controls);
275         card->controls_count += kcontrol->count;
276         kcontrol->id.numid = card->last_numid + 1;
277         card->last_numid += kcontrol->count;
278         up_write(&card->controls_rwsem);
279         id = kcontrol->id;
280         for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
281                 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
282         return 0;
283 }
284
285 /**
286  * snd_ctl_remove - remove the control from the card and release it
287  * @card: the card instance
288  * @kcontrol: the control instance to remove
289  *
290  * Removes the control from the card and then releases the instance.
291  * You don't need to call snd_ctl_free_one().
292  * 
293  * Returns 0 if successful, or a negative error code on failure.
294  */
295 int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol)
296 {
297         snd_ctl_elem_id_t id;
298         unsigned int idx;
299
300         snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
301         down_write(&card->controls_rwsem);
302         list_del(&kcontrol->list);
303         card->controls_count -= kcontrol->count;
304         up_write(&card->controls_rwsem);
305         id = kcontrol->id;
306         for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
307                 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_REMOVE, &id);
308         snd_ctl_free_one(kcontrol);
309         return 0;
310 }
311
312 /**
313  * snd_ctl_remove_id - remove the control of the given id and release it
314  * @card: the card instance
315  * @id: the control id to remove
316  *
317  * Finds the control instance with the given id, removes it from the
318  * card list and releases it.
319  * 
320  * Returns 0 if successful, or a negative error code on failure.
321  */
322 int snd_ctl_remove_id(snd_card_t * card, snd_ctl_elem_id_t *id)
323 {
324         snd_kcontrol_t *kctl;
325
326         kctl = snd_ctl_find_id(card, id);
327         if (kctl == NULL)
328                 return -ENOENT;
329         return snd_ctl_remove(card, kctl);
330 }
331
332 static snd_kcontrol_t *_ctl_find_id
333 (snd_card_t * card, snd_ctl_elem_id_t *id); /* w/o lock */
334
335 /**
336  * snd_ctl_rename_id - replace the id of a control on the card
337  * @card: the card instance
338  * @src_id: the old id
339  * @dst_id: the new id
340  *
341  * Finds the control with the old id from the card, and replaces the
342  * id with the new one.
343  *
344  * Returns zero if successful, or a negative error code on failure.
345  */
346 int snd_ctl_rename_id(snd_card_t * card, snd_ctl_elem_id_t *src_id, snd_ctl_elem_id_t *dst_id)
347 {
348         snd_kcontrol_t *kctl;
349
350         down_write(&card->controls_rwsem);
351         kctl = _ctl_find_id(card, src_id);
352         if (kctl == NULL) {
353                 up_write(&card->controls_rwsem);
354                 return -ENOENT;
355         }
356         kctl->id = *dst_id;
357         kctl->id.numid = card->last_numid + 1;
358         card->last_numid += kctl->count;
359         up_write(&card->controls_rwsem);
360         return 0;
361 }
362
363 static snd_kcontrol_t *_ctl_find_numid(snd_card_t * card, unsigned int numid)
364 {
365         struct list_head *list;
366         snd_kcontrol_t *kctl;
367
368         snd_runtime_check(card != NULL && numid != 0, return NULL);
369         list_for_each(list, &card->controls) {
370                 kctl = snd_kcontrol(list);
371                 if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
372                         return kctl;
373         }
374         return NULL;
375 }
376
377 static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
378 {
379         struct list_head *list;
380         snd_kcontrol_t *kctl;
381
382         snd_runtime_check(card != NULL && id != NULL, return NULL);
383         if (id->numid != 0)
384                 return _ctl_find_numid(card, id->numid);
385         list_for_each(list, &card->controls) {
386                 kctl = snd_kcontrol(list);
387                 if (kctl->id.iface != id->iface)
388                         continue;
389                 if (kctl->id.device != id->device)
390                         continue;
391                 if (kctl->id.subdevice != id->subdevice)
392                         continue;
393                 if (strncmp(kctl->id.name, id->name, sizeof(kctl->id.name)))
394                         continue;
395                 if (kctl->id.index > id->index)
396                         continue;
397                 if (kctl->id.index + kctl->count <= id->index)
398                         continue;
399                 return kctl;
400         }
401         return NULL;
402 }
403
404 /**
405  * snd_ctl_find_id - find the control instance with the given id
406  * @card: the card instance
407  * @id: the id to search
408  *
409  * Finds the control instance with the given id from the card.
410  *
411  * Returns the pointer of the instance if found, or NULL if not.
412  */
413 snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
414 {
415         snd_kcontrol_t *kctl;
416         down_read(&card->controls_rwsem);
417         kctl = _ctl_find_id(card, id);
418         up_read(&card->controls_rwsem);
419         return kctl;
420 }
421
422 /**
423  * snd_ctl_find_numid - find the control instance with the given number-id
424  * @card: the card instance
425  * @numid: the number-id to search
426  *
427  * Finds the control instance with the given number-id from the card.
428  *
429  * Returns the pointer of the instance if found, or NULL if not.
430  */
431 snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid)
432 {
433         snd_kcontrol_t *kctl;
434         down_read(&card->controls_rwsem);
435         kctl = _ctl_find_numid(card, numid);
436         up_read(&card->controls_rwsem);
437         return kctl;
438 }
439
440 static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl,
441                              unsigned int cmd, unsigned long arg)
442 {
443         snd_ctl_card_info_t info;
444
445         memset(&info, 0, sizeof(info));
446         down_read(&snd_ioctl_rwsem);
447         info.card = card->number;
448         strlcpy(info.id, card->id, sizeof(info.id));
449         strlcpy(info.driver, card->driver, sizeof(info.driver));
450         strlcpy(info.name, card->shortname, sizeof(info.name));
451         strlcpy(info.longname, card->longname, sizeof(info.longname));
452         strlcpy(info.mixername, card->mixername, sizeof(info.mixername));
453         strlcpy(info.components, card->components, sizeof(info.components));
454         up_read(&snd_ioctl_rwsem);
455         if (copy_to_user((void *) arg, &info, sizeof(snd_ctl_card_info_t)))
456                 return -EFAULT;
457         return 0;
458 }
459
460 static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t *_list)
461 {
462         struct list_head *plist;
463         snd_ctl_elem_list_t list;
464         snd_kcontrol_t *kctl;
465         snd_ctl_elem_id_t *dst, *id;
466         unsigned int offset, space, first, jidx;
467         
468         if (copy_from_user(&list, _list, sizeof(list)))
469                 return -EFAULT;
470         offset = list.offset;
471         space = list.space;
472         first = 0;
473         /* try limit maximum space */
474         if (space > 16384)
475                 return -ENOMEM;
476         if (space > 0) {
477                 /* allocate temporary buffer for atomic operation */
478                 dst = vmalloc(space * sizeof(snd_ctl_elem_id_t));
479                 if (dst == NULL)
480                         return -ENOMEM;
481                 down_read(&card->controls_rwsem);
482                 list.count = card->controls_count;
483                 plist = card->controls.next;
484                 while (plist != &card->controls) {
485                         if (offset == 0)
486                                 break;
487                         kctl = snd_kcontrol(plist);
488                         if (offset < kctl->count)
489                                 break;
490                         offset -= kctl->count;
491                         plist = plist->next;
492                 }
493                 list.used = 0;
494                 id = dst;
495                 while (space > 0 && plist != &card->controls) {
496                         kctl = snd_kcontrol(plist);
497                         for (jidx = offset; space > 0 && jidx < kctl->count; jidx++) {
498                                 snd_ctl_build_ioff(id, kctl, jidx);
499                                 id++;
500                                 space--;
501                                 list.used++;
502                         }
503                         plist = plist->next;
504                         offset = 0;
505                 }
506                 up_read(&card->controls_rwsem);
507                 if (list.used > 0 && copy_to_user(list.pids, dst, list.used * sizeof(snd_ctl_elem_id_t))) {
508                         vfree(dst);
509                         return -EFAULT;
510                 }
511                 vfree(dst);
512         } else {
513                 down_read(&card->controls_rwsem);
514                 list.count = card->controls_count;
515                 up_read(&card->controls_rwsem);
516         }
517         if (copy_to_user(_list, &list, sizeof(list)))
518                 return -EFAULT;
519         return 0;
520 }
521
522 static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t *_info)
523 {
524         snd_card_t *card = ctl->card;
525         snd_ctl_elem_info_t info;
526         snd_kcontrol_t *kctl;
527         snd_kcontrol_volatile_t *vd;
528         unsigned int index_offset;
529         int result;
530         
531         if (copy_from_user(&info, _info, sizeof(info)))
532                 return -EFAULT;
533         down_read(&card->controls_rwsem);
534         kctl = _ctl_find_id(card, &info.id);
535         if (kctl == NULL) {
536                 up_read(&card->controls_rwsem);
537                 return -ENOENT;
538         }
539 #ifdef CONFIG_SND_DEBUG
540         info.access = 0;
541 #endif
542         result = kctl->info(kctl, &info);
543         if (result >= 0) {
544                 snd_assert(info.access == 0, );
545                 index_offset = snd_ctl_get_ioff(kctl, &info.id);
546                 vd = &kctl->vd[index_offset];
547                 snd_ctl_build_ioff(&info.id, kctl, index_offset);
548                 info.access = vd->access;
549                 if (vd->owner) {
550                         info.access |= SNDRV_CTL_ELEM_ACCESS_LOCK;
551                         if (vd->owner == ctl)
552                                 info.access |= SNDRV_CTL_ELEM_ACCESS_OWNER;
553                         info.owner = vd->owner_pid;
554                 } else {
555                         info.owner = -1;
556                 }
557         }
558         up_read(&card->controls_rwsem);
559         if (result >= 0)
560                 if (copy_to_user(_info, &info, sizeof(info)))
561                         return -EFAULT;
562         return result;
563 }
564
565 static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control)
566 {
567
568         snd_ctl_elem_value_t *control;
569         snd_kcontrol_t *kctl;
570         snd_kcontrol_volatile_t *vd;
571         unsigned int index_offset;
572         int result, indirect;
573         
574         control = kmalloc(sizeof(*control), GFP_KERNEL);
575         if (control == NULL)
576                 return -ENOMEM; 
577         if (copy_from_user(control, _control, sizeof(*control)))
578                 return -EFAULT;
579         down_read(&card->controls_rwsem);
580         kctl = _ctl_find_id(card, &control->id);
581         if (kctl == NULL) {
582                 result = -ENOENT;
583         } else {
584                 index_offset = snd_ctl_get_ioff(kctl, &control->id);
585                 vd = &kctl->vd[index_offset];
586                 indirect = vd->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0;
587                 if (control->indirect != indirect) {
588                         result = -EACCES;
589                 } else {
590                         if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get != NULL) {
591                                 snd_ctl_build_ioff(&control->id, kctl, index_offset);
592                                 result = kctl->get(kctl, control);
593                         } else {
594                                 result = -EPERM;
595                         }
596                 }
597         }
598         up_read(&card->controls_rwsem);
599         if (result >= 0)
600                 if (copy_to_user(_control, control, sizeof(*control)))
601                         return -EFAULT;
602         kfree(control);
603         return result;
604 }
605
606 static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_control)
607 {
608         snd_card_t *card = file->card;
609         snd_ctl_elem_value_t *control;
610         snd_kcontrol_t *kctl;
611         snd_kcontrol_volatile_t *vd;
612         unsigned int index_offset;
613         int result, indirect;
614
615         control = kmalloc(sizeof(*control), GFP_KERNEL);
616         if (control == NULL)
617                 return -ENOMEM; 
618         if (copy_from_user(control, _control, sizeof(*control)))
619                 return -EFAULT;
620         down_read(&card->controls_rwsem);
621         kctl = _ctl_find_id(card, &control->id);
622         if (kctl == NULL) {
623                 result = -ENOENT;
624         } else {
625                 index_offset = snd_ctl_get_ioff(kctl, &control->id);
626                 vd = &kctl->vd[index_offset];
627                 indirect = vd->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0;
628                 if (control->indirect != indirect) {
629                         result = -EACCES;
630                 } else {
631                         if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
632                             kctl->put == NULL ||
633                             (vd->owner != NULL && vd->owner != file)) {
634                                 result = -EPERM;
635                         } else {
636                                 snd_ctl_build_ioff(&control->id, kctl, index_offset);
637                                 result = kctl->put(kctl, control);
638                         }
639                         if (result > 0) {
640                                 up_read(&card->controls_rwsem);
641                                 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &control->id);
642                                 result = 0;
643                                 goto __unlocked;
644                         }
645                 }
646         }
647         up_read(&card->controls_rwsem);
648       __unlocked:
649         if (result >= 0)
650                 if (copy_to_user(_control, control, sizeof(*control)))
651                         return -EFAULT;
652         kfree(control);
653         return result;
654 }
655
656 static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id)
657 {
658         snd_card_t *card = file->card;
659         snd_ctl_elem_id_t id;
660         snd_kcontrol_t *kctl;
661         snd_kcontrol_volatile_t *vd;
662         int result;
663         
664         if (copy_from_user(&id, _id, sizeof(id)))
665                 return -EFAULT;
666         down_write(&card->controls_rwsem);
667         kctl = _ctl_find_id(card, &id);
668         if (kctl == NULL) {
669                 result = -ENOENT;
670         } else {
671                 vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
672                 if (vd->owner != NULL)
673                         result = -EBUSY;
674                 else {
675                         vd->owner = file;
676                         vd->owner_pid = current->pid;
677                         result = 0;
678                 }
679         }
680         up_write(&card->controls_rwsem);
681         return result;
682 }
683
684 static int snd_ctl_elem_unlock(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id)
685 {
686         snd_card_t *card = file->card;
687         snd_ctl_elem_id_t id;
688         snd_kcontrol_t *kctl;
689         snd_kcontrol_volatile_t *vd;
690         int result;
691         
692         if (copy_from_user(&id, _id, sizeof(id)))
693                 return -EFAULT;
694         down_write(&card->controls_rwsem);
695         kctl = _ctl_find_id(card, &id);
696         if (kctl == NULL) {
697                 result = -ENOENT;
698         } else {
699                 vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
700                 if (vd->owner == NULL)
701                         result = -EINVAL;
702                 else if (vd->owner != file)
703                         result = -EPERM;
704                 else {
705                         vd->owner = NULL;
706                         vd->owner_pid = 0;
707                         result = 0;
708                 }
709         }
710         up_write(&card->controls_rwsem);
711         return result;
712 }
713
714 static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int *ptr)
715 {
716         int subscribe;
717         if (get_user(subscribe, ptr))
718                 return -EFAULT;
719         if (subscribe < 0) {
720                 subscribe = file->subscribed;
721                 if (put_user(subscribe, ptr))
722                         return -EFAULT;
723                 return 0;
724         }
725         if (subscribe) {
726                 file->subscribed = 1;
727                 return 0;
728         } else if (file->subscribed) {
729                 snd_ctl_empty_read_queue(file);
730                 file->subscribed = 0;
731         }
732         return 0;
733 }
734
735 static int snd_ctl_ioctl(struct inode *inode, struct file *file,
736                          unsigned int cmd, unsigned long arg)
737 {
738         snd_ctl_file_t *ctl;
739         snd_card_t *card;
740         struct list_head *list;
741         snd_kctl_ioctl_t *p;
742         int err;
743
744         ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO);
745         card = ctl->card;
746         snd_assert(card != NULL, return -ENXIO);
747         switch (cmd) {
748         case SNDRV_CTL_IOCTL_PVERSION:
749                 return put_user(SNDRV_CTL_VERSION, (int *)arg) ? -EFAULT : 0;
750         case SNDRV_CTL_IOCTL_CARD_INFO:
751                 return snd_ctl_card_info(card, ctl, cmd, arg);
752         case SNDRV_CTL_IOCTL_ELEM_LIST:
753                 return snd_ctl_elem_list(ctl->card, (snd_ctl_elem_list_t *) arg);
754         case SNDRV_CTL_IOCTL_ELEM_INFO:
755                 return snd_ctl_elem_info(ctl, (snd_ctl_elem_info_t *) arg);
756         case SNDRV_CTL_IOCTL_ELEM_READ:
757                 return snd_ctl_elem_read(ctl->card, (snd_ctl_elem_value_t *) arg);
758         case SNDRV_CTL_IOCTL_ELEM_WRITE:
759                 return snd_ctl_elem_write(ctl, (snd_ctl_elem_value_t *) arg);
760         case SNDRV_CTL_IOCTL_ELEM_LOCK:
761                 return snd_ctl_elem_lock(ctl, (snd_ctl_elem_id_t *) arg);
762         case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
763                 return snd_ctl_elem_unlock(ctl, (snd_ctl_elem_id_t *) arg);
764         case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
765                 return snd_ctl_subscribe_events(ctl, (int *) arg);
766         case SNDRV_CTL_IOCTL_POWER:
767                 if (get_user(err, (int *)arg))
768                         return -EFAULT;
769                 if (!capable(CAP_SYS_ADMIN))
770                         return -EPERM;
771 #ifdef CONFIG_PM
772                 if (card->set_power_state) {
773                         snd_power_lock(card);
774                         err = card->set_power_state(card, err);
775                         snd_power_unlock(card);
776                 } else
777 #endif
778                         err = -ENOPROTOOPT;
779                 return err;
780         case SNDRV_CTL_IOCTL_POWER_STATE:
781 #ifdef CONFIG_PM
782                 return put_user(card->power_state, (int *)arg) ? -EFAULT : 0;
783 #else
784                 return put_user(SNDRV_CTL_POWER_D0, (int *)arg) ? -EFAULT : 0;
785 #endif
786         }
787         down_read(&snd_ioctl_rwsem);
788         list_for_each(list, &snd_control_ioctls) {
789                 p = list_entry(list, snd_kctl_ioctl_t, list);
790                 err = p->fioctl(card, ctl, cmd, arg);
791                 if (err != -ENOIOCTLCMD) {
792                         up_read(&snd_ioctl_rwsem);
793                         return err;
794                 }
795         }
796         up_read(&snd_ioctl_rwsem);
797         snd_printd("unknown ioctl = 0x%x\n", cmd);
798         return -ENOTTY;
799 }
800
801 static ssize_t snd_ctl_read(struct file *file, char *buffer, size_t count, loff_t * offset)
802 {
803         snd_ctl_file_t *ctl;
804         int err = 0;
805         ssize_t result = 0;
806
807         ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO);
808         snd_assert(ctl != NULL && ctl->card != NULL, return -ENXIO);
809         if (!ctl->subscribed)
810                 return -EBADFD;
811         if (count < sizeof(snd_ctl_event_t))
812                 return -EINVAL;
813         spin_lock_irq(&ctl->read_lock);
814         while (count >= sizeof(snd_ctl_event_t)) {
815                 snd_ctl_event_t ev;
816                 snd_kctl_event_t *kev;
817                 while (list_empty(&ctl->events)) {
818                         wait_queue_t wait;
819                         if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
820                                 err = -EAGAIN;
821                                 goto __end;
822                         }
823                         init_waitqueue_entry(&wait, current);
824                         add_wait_queue(&ctl->change_sleep, &wait);
825                         spin_unlock_irq(&ctl->read_lock);
826                         set_current_state(TASK_INTERRUPTIBLE);
827                         schedule();
828                         set_current_state(TASK_RUNNING);
829                         remove_wait_queue(&ctl->change_sleep, &wait);
830                         if (signal_pending(current))
831                                 return result > 0 ? result : -ERESTARTSYS;
832                         spin_lock_irq(&ctl->read_lock);
833                 }
834                 kev = snd_kctl_event(ctl->events.next);
835                 ev.type = SNDRV_CTL_EVENT_ELEM;
836                 ev.data.elem.mask = kev->mask;
837                 ev.data.elem.id = kev->id;
838                 list_del(&kev->list);
839                 spin_unlock_irq(&ctl->read_lock);
840                 kfree(kev);
841                 if (copy_to_user(buffer, &ev, sizeof(snd_ctl_event_t))) {
842                         err = -EFAULT;
843                         goto __end;
844                 }
845                 spin_lock_irq(&ctl->read_lock);
846                 buffer += sizeof(snd_ctl_event_t);
847                 count -= sizeof(snd_ctl_event_t);
848                 result += sizeof(snd_ctl_event_t);
849         }
850       __end:
851         spin_unlock_irq(&ctl->read_lock);
852         return result > 0 ? result : err;
853 }
854
855 static unsigned int snd_ctl_poll(struct file *file, poll_table * wait)
856 {
857         unsigned int mask;
858         snd_ctl_file_t *ctl;
859
860         ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return 0);
861         if (!ctl->subscribed)
862                 return 0;
863         poll_wait(file, &ctl->change_sleep, wait);
864
865         mask = 0;
866         if (!list_empty(&ctl->events))
867                 mask |= POLLIN | POLLRDNORM;
868
869         return mask;
870 }
871
872 /*
873  * register the device-specific control-ioctls.
874  * called from each device manager like pcm.c, hwdep.c, etc.
875  */
876 int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
877 {
878         snd_kctl_ioctl_t *pn;
879
880         pn = (snd_kctl_ioctl_t *)
881                 snd_kcalloc(sizeof(snd_kctl_ioctl_t), GFP_KERNEL);
882         if (pn == NULL)
883                 return -ENOMEM;
884         pn->fioctl = fcn;
885         down_write(&snd_ioctl_rwsem);
886         list_add_tail(&pn->list, &snd_control_ioctls);
887         up_write(&snd_ioctl_rwsem);
888         return 0;
889 }
890
891 /*
892  * de-register the device-specific control-ioctls.
893  */
894 int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
895 {
896         struct list_head *list;
897         snd_kctl_ioctl_t *p;
898
899         snd_runtime_check(fcn != NULL, return -EINVAL);
900         down_write(&snd_ioctl_rwsem);
901         list_for_each(list, &snd_control_ioctls) {
902                 p = list_entry(list, snd_kctl_ioctl_t, list);
903                 if (p->fioctl == fcn) {
904                         list_del(&p->list);
905                         up_write(&snd_ioctl_rwsem);
906                         kfree(p);
907                         return 0;
908                 }
909         }
910         up_write(&snd_ioctl_rwsem);
911         snd_BUG();
912         return -EINVAL;
913 }
914
915 static int snd_ctl_fasync(int fd, struct file * file, int on)
916 {
917         snd_ctl_file_t *ctl;
918         int err;
919         ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO);
920         err = fasync_helper(fd, file, on, &ctl->fasync);
921         if (err < 0)
922                 return err;
923         return 0;
924 }
925
926 /*
927  *  INIT PART
928  */
929
930 static struct file_operations snd_ctl_f_ops =
931 {
932         .owner =        THIS_MODULE,
933         .read =         snd_ctl_read,
934         .open =         snd_ctl_open,
935         .release =      snd_ctl_release,
936         .poll =         snd_ctl_poll,
937         .ioctl =        snd_ctl_ioctl,
938         .fasync =       snd_ctl_fasync,
939 };
940
941 static snd_minor_t snd_ctl_reg =
942 {
943         .comment =      "ctl",
944         .f_ops =        &snd_ctl_f_ops,
945 };
946
947 /*
948  * registration of the control device:
949  * called from init.c
950  */
951 int snd_ctl_register(snd_card_t *card)
952 {
953         int err, cardnum;
954         char name[16];
955
956         snd_assert(card != NULL, return -ENXIO);
957         cardnum = card->number;
958         snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
959         sprintf(name, "controlC%i", cardnum);
960         if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL,
961                                         card, 0, &snd_ctl_reg, name)) < 0)
962                 return err;
963         return 0;
964 }
965
966 /*
967  * disconnection of the control device:
968  * called from init.c
969  */
970 int snd_ctl_disconnect(snd_card_t *card)
971 {
972         struct list_head *flist;
973         snd_ctl_file_t *ctl;
974
975         down_read(&card->controls_rwsem);
976         list_for_each(flist, &card->ctl_files) {
977                 ctl = snd_ctl_file(flist);
978                 wake_up(&ctl->change_sleep);
979                 kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
980         }
981         up_read(&card->controls_rwsem);
982         return 0;
983 }
984
985 /*
986  * de-registration of the control device:
987  * called from init.c
988  */
989 int snd_ctl_unregister(snd_card_t *card)
990 {
991         int err, cardnum;
992         snd_kcontrol_t *control;
993
994         snd_assert(card != NULL, return -ENXIO);
995         cardnum = card->number;
996         snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
997         if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL, card, 0)) < 0)
998                 return err;
999         while (!list_empty(&card->controls)) {
1000                 control = snd_kcontrol(card->controls.next);
1001                 snd_ctl_remove(card, control);
1002         }
1003         return 0;
1004 }