ccwgroup: move attributes to attribute group
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / core / control.c
blob7834a5438f756b8aab0efd6fe77e93bb46820a1f
1 /*
2 * Routines for driver control interface
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
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.
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.
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
22 #include <linux/threads.h>
23 #include <linux/interrupt.h>
24 #include <linux/slab.h>
25 #include <linux/vmalloc.h>
26 #include <linux/time.h>
27 #include <sound/core.h>
28 #include <sound/minors.h>
29 #include <sound/info.h>
30 #include <sound/control.h>
32 /* max number of user-defined controls */
33 #define MAX_USER_CONTROLS 32
34 #define MAX_CONTROL_COUNT 1028
36 struct snd_kctl_ioctl {
37 struct list_head list; /* list of all ioctls */
38 snd_kctl_ioctl_func_t fioctl;
41 static DECLARE_RWSEM(snd_ioctl_rwsem);
42 static LIST_HEAD(snd_control_ioctls);
43 #ifdef CONFIG_COMPAT
44 static LIST_HEAD(snd_control_compat_ioctls);
45 #endif
47 static int snd_ctl_open(struct inode *inode, struct file *file)
49 unsigned long flags;
50 struct snd_card *card;
51 struct snd_ctl_file *ctl;
52 int err;
54 card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
55 if (!card) {
56 err = -ENODEV;
57 goto __error1;
59 err = snd_card_file_add(card, file);
60 if (err < 0) {
61 err = -ENODEV;
62 goto __error1;
64 if (!try_module_get(card->module)) {
65 err = -EFAULT;
66 goto __error2;
68 ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
69 if (ctl == NULL) {
70 err = -ENOMEM;
71 goto __error;
73 INIT_LIST_HEAD(&ctl->events);
74 init_waitqueue_head(&ctl->change_sleep);
75 spin_lock_init(&ctl->read_lock);
76 ctl->card = card;
77 ctl->prefer_pcm_subdevice = -1;
78 ctl->prefer_rawmidi_subdevice = -1;
79 ctl->pid = current->pid;
80 file->private_data = ctl;
81 write_lock_irqsave(&card->ctl_files_rwlock, flags);
82 list_add_tail(&ctl->list, &card->ctl_files);
83 write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
84 return 0;
86 __error:
87 module_put(card->module);
88 __error2:
89 snd_card_file_remove(card, file);
90 __error1:
91 return err;
94 static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl)
96 unsigned long flags;
97 struct snd_kctl_event *cread;
99 spin_lock_irqsave(&ctl->read_lock, flags);
100 while (!list_empty(&ctl->events)) {
101 cread = snd_kctl_event(ctl->events.next);
102 list_del(&cread->list);
103 kfree(cread);
105 spin_unlock_irqrestore(&ctl->read_lock, flags);
108 static int snd_ctl_release(struct inode *inode, struct file *file)
110 unsigned long flags;
111 struct snd_card *card;
112 struct snd_ctl_file *ctl;
113 struct snd_kcontrol *control;
114 unsigned int idx;
116 ctl = file->private_data;
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_entry(control, &card->controls, list)
124 for (idx = 0; idx < control->count; idx++)
125 if (control->vd[idx].owner == ctl)
126 control->vd[idx].owner = NULL;
127 up_write(&card->controls_rwsem);
128 snd_ctl_empty_read_queue(ctl);
129 kfree(ctl);
130 module_put(card->module);
131 snd_card_file_remove(card, file);
132 return 0;
135 void snd_ctl_notify(struct snd_card *card, unsigned int mask,
136 struct snd_ctl_elem_id *id)
138 unsigned long flags;
139 struct snd_ctl_file *ctl;
140 struct snd_kctl_event *ev;
142 if (snd_BUG_ON(!card || !id))
143 return;
144 read_lock(&card->ctl_files_rwlock);
145 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
146 card->mixer_oss_change_count++;
147 #endif
148 list_for_each_entry(ctl, &card->ctl_files, list) {
149 if (!ctl->subscribed)
150 continue;
151 spin_lock_irqsave(&ctl->read_lock, flags);
152 list_for_each_entry(ev, &ctl->events, list) {
153 if (ev->id.numid == id->numid) {
154 ev->mask |= mask;
155 goto _found;
158 ev = kzalloc(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");
166 _found:
167 wake_up(&ctl->change_sleep);
168 spin_unlock_irqrestore(&ctl->read_lock, flags);
169 kill_fasync(&ctl->fasync, SIGIO, POLL_IN);
171 read_unlock(&card->ctl_files_rwlock);
174 EXPORT_SYMBOL(snd_ctl_notify);
177 * snd_ctl_new - create a control instance from the template
178 * @control: the control template
179 * @access: the default control access
181 * Allocates a new struct snd_kcontrol instance and copies the given template
182 * to the new instance. It does not copy volatile data (access).
184 * Returns the pointer of the new instance, or NULL on failure.
186 static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control,
187 unsigned int access)
189 struct snd_kcontrol *kctl;
190 unsigned int idx;
192 if (snd_BUG_ON(!control || !control->count))
193 return NULL;
195 if (control->count > MAX_CONTROL_COUNT)
196 return NULL;
198 kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
199 if (kctl == NULL) {
200 snd_printk(KERN_ERR "Cannot allocate control instance\n");
201 return NULL;
203 *kctl = *control;
204 for (idx = 0; idx < kctl->count; idx++)
205 kctl->vd[idx].access = access;
206 return kctl;
210 * snd_ctl_new1 - create a control instance from the template
211 * @ncontrol: the initialization record
212 * @private_data: the private data to set
214 * Allocates a new struct snd_kcontrol instance and initialize from the given
215 * template. When the access field of ncontrol is 0, it's assumed as
216 * READWRITE access. When the count field is 0, it's assumes as one.
218 * Returns the pointer of the newly generated instance, or NULL on failure.
220 struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
221 void *private_data)
223 struct snd_kcontrol kctl;
224 unsigned int access;
226 if (snd_BUG_ON(!ncontrol || !ncontrol->info))
227 return NULL;
228 memset(&kctl, 0, sizeof(kctl));
229 kctl.id.iface = ncontrol->iface;
230 kctl.id.device = ncontrol->device;
231 kctl.id.subdevice = ncontrol->subdevice;
232 if (ncontrol->name) {
233 strlcpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name));
234 if (strcmp(ncontrol->name, kctl.id.name) != 0)
235 snd_printk(KERN_WARNING
236 "Control name '%s' truncated to '%s'\n",
237 ncontrol->name, kctl.id.name);
239 kctl.id.index = ncontrol->index;
240 kctl.count = ncontrol->count ? ncontrol->count : 1;
241 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
242 (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
243 SNDRV_CTL_ELEM_ACCESS_INACTIVE|
244 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
245 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK));
246 kctl.info = ncontrol->info;
247 kctl.get = ncontrol->get;
248 kctl.put = ncontrol->put;
249 kctl.tlv.p = ncontrol->tlv.p;
250 kctl.private_value = ncontrol->private_value;
251 kctl.private_data = private_data;
252 return snd_ctl_new(&kctl, access);
255 EXPORT_SYMBOL(snd_ctl_new1);
258 * snd_ctl_free_one - release the control instance
259 * @kcontrol: the control instance
261 * Releases the control instance created via snd_ctl_new()
262 * or snd_ctl_new1().
263 * Don't call this after the control was added to the card.
265 void snd_ctl_free_one(struct snd_kcontrol *kcontrol)
267 if (kcontrol) {
268 if (kcontrol->private_free)
269 kcontrol->private_free(kcontrol);
270 kfree(kcontrol);
274 EXPORT_SYMBOL(snd_ctl_free_one);
276 static unsigned int snd_ctl_hole_check(struct snd_card *card,
277 unsigned int count)
279 struct snd_kcontrol *kctl;
281 list_for_each_entry(kctl, &card->controls, list) {
282 if ((kctl->id.numid <= card->last_numid &&
283 kctl->id.numid + kctl->count > card->last_numid) ||
284 (kctl->id.numid <= card->last_numid + count - 1 &&
285 kctl->id.numid + kctl->count > card->last_numid + count - 1))
286 return card->last_numid = kctl->id.numid + kctl->count - 1;
288 return card->last_numid;
291 static int snd_ctl_find_hole(struct snd_card *card, unsigned int count)
293 unsigned int last_numid, iter = 100000;
295 last_numid = card->last_numid;
296 while (last_numid != snd_ctl_hole_check(card, count)) {
297 if (--iter == 0) {
298 /* this situation is very unlikely */
299 snd_printk(KERN_ERR "unable to allocate new control numid\n");
300 return -ENOMEM;
302 last_numid = card->last_numid;
304 return 0;
308 * snd_ctl_add - add the control instance to the card
309 * @card: the card instance
310 * @kcontrol: the control instance to add
312 * Adds the control instance created via snd_ctl_new() or
313 * snd_ctl_new1() to the given card. Assigns also an unique
314 * numid used for fast search.
316 * Returns zero if successful, or a negative error code on failure.
318 * It frees automatically the control which cannot be added.
320 int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
322 struct snd_ctl_elem_id id;
323 unsigned int idx;
324 int err = -EINVAL;
326 if (! kcontrol)
327 return err;
328 if (snd_BUG_ON(!card || !kcontrol->info))
329 goto error;
330 id = kcontrol->id;
331 down_write(&card->controls_rwsem);
332 if (snd_ctl_find_id(card, &id)) {
333 up_write(&card->controls_rwsem);
334 snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n",
335 id.iface,
336 id.device,
337 id.subdevice,
338 id.name,
339 id.index);
340 err = -EBUSY;
341 goto error;
343 if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
344 up_write(&card->controls_rwsem);
345 err = -ENOMEM;
346 goto error;
348 list_add_tail(&kcontrol->list, &card->controls);
349 card->controls_count += kcontrol->count;
350 kcontrol->id.numid = card->last_numid + 1;
351 card->last_numid += kcontrol->count;
352 up_write(&card->controls_rwsem);
353 for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
354 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
355 return 0;
357 error:
358 snd_ctl_free_one(kcontrol);
359 return err;
362 EXPORT_SYMBOL(snd_ctl_add);
365 * snd_ctl_remove - remove the control from the card and release it
366 * @card: the card instance
367 * @kcontrol: the control instance to remove
369 * Removes the control from the card and then releases the instance.
370 * You don't need to call snd_ctl_free_one(). You must be in
371 * the write lock - down_write(&card->controls_rwsem).
373 * Returns 0 if successful, or a negative error code on failure.
375 int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
377 struct snd_ctl_elem_id id;
378 unsigned int idx;
380 if (snd_BUG_ON(!card || !kcontrol))
381 return -EINVAL;
382 list_del(&kcontrol->list);
383 card->controls_count -= kcontrol->count;
384 id = kcontrol->id;
385 for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
386 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_REMOVE, &id);
387 snd_ctl_free_one(kcontrol);
388 return 0;
391 EXPORT_SYMBOL(snd_ctl_remove);
394 * snd_ctl_remove_id - remove the control of the given id and release it
395 * @card: the card instance
396 * @id: the control id to remove
398 * Finds the control instance with the given id, removes it from the
399 * card list and releases it.
401 * Returns 0 if successful, or a negative error code on failure.
403 int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
405 struct snd_kcontrol *kctl;
406 int ret;
408 down_write(&card->controls_rwsem);
409 kctl = snd_ctl_find_id(card, id);
410 if (kctl == NULL) {
411 up_write(&card->controls_rwsem);
412 return -ENOENT;
414 ret = snd_ctl_remove(card, kctl);
415 up_write(&card->controls_rwsem);
416 return ret;
419 EXPORT_SYMBOL(snd_ctl_remove_id);
422 * snd_ctl_remove_user_ctl - remove and release the unlocked user control
423 * @file: active control handle
424 * @id: the control id to remove
426 * Finds the control instance with the given id, removes it from the
427 * card list and releases it.
429 * Returns 0 if successful, or a negative error code on failure.
431 static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file,
432 struct snd_ctl_elem_id *id)
434 struct snd_card *card = file->card;
435 struct snd_kcontrol *kctl;
436 int idx, ret;
438 down_write(&card->controls_rwsem);
439 kctl = snd_ctl_find_id(card, id);
440 if (kctl == NULL) {
441 ret = -ENOENT;
442 goto error;
444 if (!(kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_USER)) {
445 ret = -EINVAL;
446 goto error;
448 for (idx = 0; idx < kctl->count; idx++)
449 if (kctl->vd[idx].owner != NULL && kctl->vd[idx].owner != file) {
450 ret = -EBUSY;
451 goto error;
453 ret = snd_ctl_remove(card, kctl);
454 if (ret < 0)
455 goto error;
456 card->user_ctl_count--;
457 error:
458 up_write(&card->controls_rwsem);
459 return ret;
463 * snd_ctl_rename_id - replace the id of a control on the card
464 * @card: the card instance
465 * @src_id: the old id
466 * @dst_id: the new id
468 * Finds the control with the old id from the card, and replaces the
469 * id with the new one.
471 * Returns zero if successful, or a negative error code on failure.
473 int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
474 struct snd_ctl_elem_id *dst_id)
476 struct snd_kcontrol *kctl;
478 down_write(&card->controls_rwsem);
479 kctl = snd_ctl_find_id(card, src_id);
480 if (kctl == NULL) {
481 up_write(&card->controls_rwsem);
482 return -ENOENT;
484 kctl->id = *dst_id;
485 kctl->id.numid = card->last_numid + 1;
486 card->last_numid += kctl->count;
487 up_write(&card->controls_rwsem);
488 return 0;
491 EXPORT_SYMBOL(snd_ctl_rename_id);
494 * snd_ctl_find_numid - find the control instance with the given number-id
495 * @card: the card instance
496 * @numid: the number-id to search
498 * Finds the control instance with the given number-id from the card.
500 * Returns the pointer of the instance if found, or NULL if not.
502 * The caller must down card->controls_rwsem before calling this function
503 * (if the race condition can happen).
505 struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid)
507 struct snd_kcontrol *kctl;
509 if (snd_BUG_ON(!card || !numid))
510 return NULL;
511 list_for_each_entry(kctl, &card->controls, list) {
512 if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
513 return kctl;
515 return NULL;
518 EXPORT_SYMBOL(snd_ctl_find_numid);
521 * snd_ctl_find_id - find the control instance with the given id
522 * @card: the card instance
523 * @id: the id to search
525 * Finds the control instance with the given id from the card.
527 * Returns the pointer of the instance if found, or NULL if not.
529 * The caller must down card->controls_rwsem before calling this function
530 * (if the race condition can happen).
532 struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
533 struct snd_ctl_elem_id *id)
535 struct snd_kcontrol *kctl;
537 if (snd_BUG_ON(!card || !id))
538 return NULL;
539 if (id->numid != 0)
540 return snd_ctl_find_numid(card, id->numid);
541 list_for_each_entry(kctl, &card->controls, list) {
542 if (kctl->id.iface != id->iface)
543 continue;
544 if (kctl->id.device != id->device)
545 continue;
546 if (kctl->id.subdevice != id->subdevice)
547 continue;
548 if (strncmp(kctl->id.name, id->name, sizeof(kctl->id.name)))
549 continue;
550 if (kctl->id.index > id->index)
551 continue;
552 if (kctl->id.index + kctl->count <= id->index)
553 continue;
554 return kctl;
556 return NULL;
559 EXPORT_SYMBOL(snd_ctl_find_id);
561 static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
562 unsigned int cmd, void __user *arg)
564 struct snd_ctl_card_info *info;
566 info = kzalloc(sizeof(*info), GFP_KERNEL);
567 if (! info)
568 return -ENOMEM;
569 down_read(&snd_ioctl_rwsem);
570 info->card = card->number;
571 strlcpy(info->id, card->id, sizeof(info->id));
572 strlcpy(info->driver, card->driver, sizeof(info->driver));
573 strlcpy(info->name, card->shortname, sizeof(info->name));
574 strlcpy(info->longname, card->longname, sizeof(info->longname));
575 strlcpy(info->mixername, card->mixername, sizeof(info->mixername));
576 strlcpy(info->components, card->components, sizeof(info->components));
577 up_read(&snd_ioctl_rwsem);
578 if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) {
579 kfree(info);
580 return -EFAULT;
582 kfree(info);
583 return 0;
586 static int snd_ctl_elem_list(struct snd_card *card,
587 struct snd_ctl_elem_list __user *_list)
589 struct list_head *plist;
590 struct snd_ctl_elem_list list;
591 struct snd_kcontrol *kctl;
592 struct snd_ctl_elem_id *dst, *id;
593 unsigned int offset, space, first, jidx;
595 if (copy_from_user(&list, _list, sizeof(list)))
596 return -EFAULT;
597 offset = list.offset;
598 space = list.space;
599 first = 0;
600 /* try limit maximum space */
601 if (space > 16384)
602 return -ENOMEM;
603 if (space > 0) {
604 /* allocate temporary buffer for atomic operation */
605 dst = vmalloc(space * sizeof(struct snd_ctl_elem_id));
606 if (dst == NULL)
607 return -ENOMEM;
608 down_read(&card->controls_rwsem);
609 list.count = card->controls_count;
610 plist = card->controls.next;
611 while (plist != &card->controls) {
612 if (offset == 0)
613 break;
614 kctl = snd_kcontrol(plist);
615 if (offset < kctl->count)
616 break;
617 offset -= kctl->count;
618 plist = plist->next;
620 list.used = 0;
621 id = dst;
622 while (space > 0 && plist != &card->controls) {
623 kctl = snd_kcontrol(plist);
624 for (jidx = offset; space > 0 && jidx < kctl->count; jidx++) {
625 snd_ctl_build_ioff(id, kctl, jidx);
626 id++;
627 space--;
628 list.used++;
630 plist = plist->next;
631 offset = 0;
633 up_read(&card->controls_rwsem);
634 if (list.used > 0 &&
635 copy_to_user(list.pids, dst,
636 list.used * sizeof(struct snd_ctl_elem_id))) {
637 vfree(dst);
638 return -EFAULT;
640 vfree(dst);
641 } else {
642 down_read(&card->controls_rwsem);
643 list.count = card->controls_count;
644 up_read(&card->controls_rwsem);
646 if (copy_to_user(_list, &list, sizeof(list)))
647 return -EFAULT;
648 return 0;
651 static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
652 struct snd_ctl_elem_info *info)
654 struct snd_card *card = ctl->card;
655 struct snd_kcontrol *kctl;
656 struct snd_kcontrol_volatile *vd;
657 unsigned int index_offset;
658 int result;
660 down_read(&card->controls_rwsem);
661 kctl = snd_ctl_find_id(card, &info->id);
662 if (kctl == NULL) {
663 up_read(&card->controls_rwsem);
664 return -ENOENT;
666 #ifdef CONFIG_SND_DEBUG
667 info->access = 0;
668 #endif
669 result = kctl->info(kctl, info);
670 if (result >= 0) {
671 snd_BUG_ON(info->access);
672 index_offset = snd_ctl_get_ioff(kctl, &info->id);
673 vd = &kctl->vd[index_offset];
674 snd_ctl_build_ioff(&info->id, kctl, index_offset);
675 info->access = vd->access;
676 if (vd->owner) {
677 info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK;
678 if (vd->owner == ctl)
679 info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER;
680 info->owner = vd->owner_pid;
681 } else {
682 info->owner = -1;
685 up_read(&card->controls_rwsem);
686 return result;
689 static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
690 struct snd_ctl_elem_info __user *_info)
692 struct snd_ctl_elem_info info;
693 int result;
695 if (copy_from_user(&info, _info, sizeof(info)))
696 return -EFAULT;
697 snd_power_lock(ctl->card);
698 result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
699 if (result >= 0)
700 result = snd_ctl_elem_info(ctl, &info);
701 snd_power_unlock(ctl->card);
702 if (result >= 0)
703 if (copy_to_user(_info, &info, sizeof(info)))
704 return -EFAULT;
705 return result;
708 static int snd_ctl_elem_read(struct snd_card *card,
709 struct snd_ctl_elem_value *control)
711 struct snd_kcontrol *kctl;
712 struct snd_kcontrol_volatile *vd;
713 unsigned int index_offset;
714 int result;
716 down_read(&card->controls_rwsem);
717 kctl = snd_ctl_find_id(card, &control->id);
718 if (kctl == NULL) {
719 result = -ENOENT;
720 } else {
721 index_offset = snd_ctl_get_ioff(kctl, &control->id);
722 vd = &kctl->vd[index_offset];
723 if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) &&
724 kctl->get != NULL) {
725 snd_ctl_build_ioff(&control->id, kctl, index_offset);
726 result = kctl->get(kctl, control);
727 } else
728 result = -EPERM;
730 up_read(&card->controls_rwsem);
731 return result;
734 static int snd_ctl_elem_read_user(struct snd_card *card,
735 struct snd_ctl_elem_value __user *_control)
737 struct snd_ctl_elem_value *control;
738 int result;
740 control = memdup_user(_control, sizeof(*control));
741 if (IS_ERR(control))
742 return PTR_ERR(control);
744 snd_power_lock(card);
745 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
746 if (result >= 0)
747 result = snd_ctl_elem_read(card, control);
748 snd_power_unlock(card);
749 if (result >= 0)
750 if (copy_to_user(_control, control, sizeof(*control)))
751 result = -EFAULT;
752 kfree(control);
753 return result;
756 static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
757 struct snd_ctl_elem_value *control)
759 struct snd_kcontrol *kctl;
760 struct snd_kcontrol_volatile *vd;
761 unsigned int index_offset;
762 int result;
764 down_read(&card->controls_rwsem);
765 kctl = snd_ctl_find_id(card, &control->id);
766 if (kctl == NULL) {
767 result = -ENOENT;
768 } else {
769 index_offset = snd_ctl_get_ioff(kctl, &control->id);
770 vd = &kctl->vd[index_offset];
771 if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
772 kctl->put == NULL ||
773 (file && vd->owner && vd->owner != file)) {
774 result = -EPERM;
775 } else {
776 snd_ctl_build_ioff(&control->id, kctl, index_offset);
777 result = kctl->put(kctl, control);
779 if (result > 0) {
780 up_read(&card->controls_rwsem);
781 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
782 &control->id);
783 return 0;
786 up_read(&card->controls_rwsem);
787 return result;
790 static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
791 struct snd_ctl_elem_value __user *_control)
793 struct snd_ctl_elem_value *control;
794 struct snd_card *card;
795 int result;
797 control = memdup_user(_control, sizeof(*control));
798 if (IS_ERR(control))
799 return PTR_ERR(control);
801 card = file->card;
802 snd_power_lock(card);
803 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
804 if (result >= 0)
805 result = snd_ctl_elem_write(card, file, control);
806 snd_power_unlock(card);
807 if (result >= 0)
808 if (copy_to_user(_control, control, sizeof(*control)))
809 result = -EFAULT;
810 kfree(control);
811 return result;
814 static int snd_ctl_elem_lock(struct snd_ctl_file *file,
815 struct snd_ctl_elem_id __user *_id)
817 struct snd_card *card = file->card;
818 struct snd_ctl_elem_id id;
819 struct snd_kcontrol *kctl;
820 struct snd_kcontrol_volatile *vd;
821 int result;
823 if (copy_from_user(&id, _id, sizeof(id)))
824 return -EFAULT;
825 down_write(&card->controls_rwsem);
826 kctl = snd_ctl_find_id(card, &id);
827 if (kctl == NULL) {
828 result = -ENOENT;
829 } else {
830 vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
831 if (vd->owner != NULL)
832 result = -EBUSY;
833 else {
834 vd->owner = file;
835 vd->owner_pid = current->pid;
836 result = 0;
839 up_write(&card->controls_rwsem);
840 return result;
843 static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
844 struct snd_ctl_elem_id __user *_id)
846 struct snd_card *card = file->card;
847 struct snd_ctl_elem_id id;
848 struct snd_kcontrol *kctl;
849 struct snd_kcontrol_volatile *vd;
850 int result;
852 if (copy_from_user(&id, _id, sizeof(id)))
853 return -EFAULT;
854 down_write(&card->controls_rwsem);
855 kctl = snd_ctl_find_id(card, &id);
856 if (kctl == NULL) {
857 result = -ENOENT;
858 } else {
859 vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
860 if (vd->owner == NULL)
861 result = -EINVAL;
862 else if (vd->owner != file)
863 result = -EPERM;
864 else {
865 vd->owner = NULL;
866 vd->owner_pid = 0;
867 result = 0;
870 up_write(&card->controls_rwsem);
871 return result;
874 struct user_element {
875 struct snd_ctl_elem_info info;
876 void *elem_data; /* element data */
877 unsigned long elem_data_size; /* size of element data in bytes */
878 void *tlv_data; /* TLV data */
879 unsigned long tlv_data_size; /* TLV data size */
880 void *priv_data; /* private data (like strings for enumerated type) */
881 unsigned long priv_data_size; /* size of private data in bytes */
884 static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
885 struct snd_ctl_elem_info *uinfo)
887 struct user_element *ue = kcontrol->private_data;
889 *uinfo = ue->info;
890 return 0;
893 static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
894 struct snd_ctl_elem_value *ucontrol)
896 struct user_element *ue = kcontrol->private_data;
898 memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size);
899 return 0;
902 static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
903 struct snd_ctl_elem_value *ucontrol)
905 int change;
906 struct user_element *ue = kcontrol->private_data;
908 change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0;
909 if (change)
910 memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
911 return change;
914 static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
915 int op_flag,
916 unsigned int size,
917 unsigned int __user *tlv)
919 struct user_element *ue = kcontrol->private_data;
920 int change = 0;
921 void *new_data;
923 if (op_flag > 0) {
924 if (size > 1024 * 128) /* sane value */
925 return -EINVAL;
927 new_data = memdup_user(tlv, size);
928 if (IS_ERR(new_data))
929 return PTR_ERR(new_data);
930 change = ue->tlv_data_size != size;
931 if (!change)
932 change = memcmp(ue->tlv_data, new_data, size);
933 kfree(ue->tlv_data);
934 ue->tlv_data = new_data;
935 ue->tlv_data_size = size;
936 } else {
937 if (! ue->tlv_data_size || ! ue->tlv_data)
938 return -ENXIO;
939 if (size < ue->tlv_data_size)
940 return -ENOSPC;
941 if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
942 return -EFAULT;
944 return change;
947 static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol)
949 struct user_element *ue = kcontrol->private_data;
950 if (ue->tlv_data)
951 kfree(ue->tlv_data);
952 kfree(ue);
955 static int snd_ctl_elem_add(struct snd_ctl_file *file,
956 struct snd_ctl_elem_info *info, int replace)
958 struct snd_card *card = file->card;
959 struct snd_kcontrol kctl, *_kctl;
960 unsigned int access;
961 long private_size;
962 struct user_element *ue;
963 int idx, err;
965 if (card->user_ctl_count >= MAX_USER_CONTROLS)
966 return -ENOMEM;
967 if (info->count < 1)
968 return -EINVAL;
969 access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
970 (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
971 SNDRV_CTL_ELEM_ACCESS_INACTIVE|
972 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE));
973 info->id.numid = 0;
974 memset(&kctl, 0, sizeof(kctl));
975 down_write(&card->controls_rwsem);
976 _kctl = snd_ctl_find_id(card, &info->id);
977 err = 0;
978 if (_kctl) {
979 if (replace)
980 err = snd_ctl_remove(card, _kctl);
981 else
982 err = -EBUSY;
983 } else {
984 if (replace)
985 err = -ENOENT;
987 up_write(&card->controls_rwsem);
988 if (err < 0)
989 return err;
990 memcpy(&kctl.id, &info->id, sizeof(info->id));
991 kctl.count = info->owner ? info->owner : 1;
992 access |= SNDRV_CTL_ELEM_ACCESS_USER;
993 kctl.info = snd_ctl_elem_user_info;
994 if (access & SNDRV_CTL_ELEM_ACCESS_READ)
995 kctl.get = snd_ctl_elem_user_get;
996 if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
997 kctl.put = snd_ctl_elem_user_put;
998 if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) {
999 kctl.tlv.c = snd_ctl_elem_user_tlv;
1000 access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1002 switch (info->type) {
1003 case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
1004 case SNDRV_CTL_ELEM_TYPE_INTEGER:
1005 private_size = sizeof(long);
1006 if (info->count > 128)
1007 return -EINVAL;
1008 break;
1009 case SNDRV_CTL_ELEM_TYPE_INTEGER64:
1010 private_size = sizeof(long long);
1011 if (info->count > 64)
1012 return -EINVAL;
1013 break;
1014 case SNDRV_CTL_ELEM_TYPE_BYTES:
1015 private_size = sizeof(unsigned char);
1016 if (info->count > 512)
1017 return -EINVAL;
1018 break;
1019 case SNDRV_CTL_ELEM_TYPE_IEC958:
1020 private_size = sizeof(struct snd_aes_iec958);
1021 if (info->count != 1)
1022 return -EINVAL;
1023 break;
1024 default:
1025 return -EINVAL;
1027 private_size *= info->count;
1028 ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL);
1029 if (ue == NULL)
1030 return -ENOMEM;
1031 ue->info = *info;
1032 ue->info.access = 0;
1033 ue->elem_data = (char *)ue + sizeof(*ue);
1034 ue->elem_data_size = private_size;
1035 kctl.private_free = snd_ctl_elem_user_free;
1036 _kctl = snd_ctl_new(&kctl, access);
1037 if (_kctl == NULL) {
1038 kfree(ue);
1039 return -ENOMEM;
1041 _kctl->private_data = ue;
1042 for (idx = 0; idx < _kctl->count; idx++)
1043 _kctl->vd[idx].owner = file;
1044 err = snd_ctl_add(card, _kctl);
1045 if (err < 0)
1046 return err;
1048 down_write(&card->controls_rwsem);
1049 card->user_ctl_count++;
1050 up_write(&card->controls_rwsem);
1052 return 0;
1055 static int snd_ctl_elem_add_user(struct snd_ctl_file *file,
1056 struct snd_ctl_elem_info __user *_info, int replace)
1058 struct snd_ctl_elem_info info;
1059 if (copy_from_user(&info, _info, sizeof(info)))
1060 return -EFAULT;
1061 return snd_ctl_elem_add(file, &info, replace);
1064 static int snd_ctl_elem_remove(struct snd_ctl_file *file,
1065 struct snd_ctl_elem_id __user *_id)
1067 struct snd_ctl_elem_id id;
1069 if (copy_from_user(&id, _id, sizeof(id)))
1070 return -EFAULT;
1071 return snd_ctl_remove_user_ctl(file, &id);
1074 static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
1076 int subscribe;
1077 if (get_user(subscribe, ptr))
1078 return -EFAULT;
1079 if (subscribe < 0) {
1080 subscribe = file->subscribed;
1081 if (put_user(subscribe, ptr))
1082 return -EFAULT;
1083 return 0;
1085 if (subscribe) {
1086 file->subscribed = 1;
1087 return 0;
1088 } else if (file->subscribed) {
1089 snd_ctl_empty_read_queue(file);
1090 file->subscribed = 0;
1092 return 0;
1095 static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1096 struct snd_ctl_tlv __user *_tlv,
1097 int op_flag)
1099 struct snd_card *card = file->card;
1100 struct snd_ctl_tlv tlv;
1101 struct snd_kcontrol *kctl;
1102 struct snd_kcontrol_volatile *vd;
1103 unsigned int len;
1104 int err = 0;
1106 if (copy_from_user(&tlv, _tlv, sizeof(tlv)))
1107 return -EFAULT;
1108 if (tlv.length < sizeof(unsigned int) * 3)
1109 return -EINVAL;
1110 down_read(&card->controls_rwsem);
1111 kctl = snd_ctl_find_numid(card, tlv.numid);
1112 if (kctl == NULL) {
1113 err = -ENOENT;
1114 goto __kctl_end;
1116 if (kctl->tlv.p == NULL) {
1117 err = -ENXIO;
1118 goto __kctl_end;
1120 vd = &kctl->vd[tlv.numid - kctl->id.numid];
1121 if ((op_flag == 0 && (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) == 0) ||
1122 (op_flag > 0 && (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) == 0) ||
1123 (op_flag < 0 && (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND) == 0)) {
1124 err = -ENXIO;
1125 goto __kctl_end;
1127 if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
1128 if (file && vd->owner != NULL && vd->owner != file) {
1129 err = -EPERM;
1130 goto __kctl_end;
1132 err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
1133 if (err > 0) {
1134 up_read(&card->controls_rwsem);
1135 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
1136 return 0;
1138 } else {
1139 if (op_flag) {
1140 err = -ENXIO;
1141 goto __kctl_end;
1143 len = kctl->tlv.p[1] + 2 * sizeof(unsigned int);
1144 if (tlv.length < len) {
1145 err = -ENOMEM;
1146 goto __kctl_end;
1148 if (copy_to_user(_tlv->tlv, kctl->tlv.p, len))
1149 err = -EFAULT;
1151 __kctl_end:
1152 up_read(&card->controls_rwsem);
1153 return err;
1156 static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1158 struct snd_ctl_file *ctl;
1159 struct snd_card *card;
1160 struct snd_kctl_ioctl *p;
1161 void __user *argp = (void __user *)arg;
1162 int __user *ip = argp;
1163 int err;
1165 ctl = file->private_data;
1166 card = ctl->card;
1167 if (snd_BUG_ON(!card))
1168 return -ENXIO;
1169 switch (cmd) {
1170 case SNDRV_CTL_IOCTL_PVERSION:
1171 return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0;
1172 case SNDRV_CTL_IOCTL_CARD_INFO:
1173 return snd_ctl_card_info(card, ctl, cmd, argp);
1174 case SNDRV_CTL_IOCTL_ELEM_LIST:
1175 return snd_ctl_elem_list(card, argp);
1176 case SNDRV_CTL_IOCTL_ELEM_INFO:
1177 return snd_ctl_elem_info_user(ctl, argp);
1178 case SNDRV_CTL_IOCTL_ELEM_READ:
1179 return snd_ctl_elem_read_user(card, argp);
1180 case SNDRV_CTL_IOCTL_ELEM_WRITE:
1181 return snd_ctl_elem_write_user(ctl, argp);
1182 case SNDRV_CTL_IOCTL_ELEM_LOCK:
1183 return snd_ctl_elem_lock(ctl, argp);
1184 case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
1185 return snd_ctl_elem_unlock(ctl, argp);
1186 case SNDRV_CTL_IOCTL_ELEM_ADD:
1187 return snd_ctl_elem_add_user(ctl, argp, 0);
1188 case SNDRV_CTL_IOCTL_ELEM_REPLACE:
1189 return snd_ctl_elem_add_user(ctl, argp, 1);
1190 case SNDRV_CTL_IOCTL_ELEM_REMOVE:
1191 return snd_ctl_elem_remove(ctl, argp);
1192 case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
1193 return snd_ctl_subscribe_events(ctl, ip);
1194 case SNDRV_CTL_IOCTL_TLV_READ:
1195 return snd_ctl_tlv_ioctl(ctl, argp, 0);
1196 case SNDRV_CTL_IOCTL_TLV_WRITE:
1197 return snd_ctl_tlv_ioctl(ctl, argp, 1);
1198 case SNDRV_CTL_IOCTL_TLV_COMMAND:
1199 return snd_ctl_tlv_ioctl(ctl, argp, -1);
1200 case SNDRV_CTL_IOCTL_POWER:
1201 return -ENOPROTOOPT;
1202 case SNDRV_CTL_IOCTL_POWER_STATE:
1203 #ifdef CONFIG_PM
1204 return put_user(card->power_state, ip) ? -EFAULT : 0;
1205 #else
1206 return put_user(SNDRV_CTL_POWER_D0, ip) ? -EFAULT : 0;
1207 #endif
1209 down_read(&snd_ioctl_rwsem);
1210 list_for_each_entry(p, &snd_control_ioctls, list) {
1211 err = p->fioctl(card, ctl, cmd, arg);
1212 if (err != -ENOIOCTLCMD) {
1213 up_read(&snd_ioctl_rwsem);
1214 return err;
1217 up_read(&snd_ioctl_rwsem);
1218 snd_printdd("unknown ioctl = 0x%x\n", cmd);
1219 return -ENOTTY;
1222 static ssize_t snd_ctl_read(struct file *file, char __user *buffer,
1223 size_t count, loff_t * offset)
1225 struct snd_ctl_file *ctl;
1226 int err = 0;
1227 ssize_t result = 0;
1229 ctl = file->private_data;
1230 if (snd_BUG_ON(!ctl || !ctl->card))
1231 return -ENXIO;
1232 if (!ctl->subscribed)
1233 return -EBADFD;
1234 if (count < sizeof(struct snd_ctl_event))
1235 return -EINVAL;
1236 spin_lock_irq(&ctl->read_lock);
1237 while (count >= sizeof(struct snd_ctl_event)) {
1238 struct snd_ctl_event ev;
1239 struct snd_kctl_event *kev;
1240 while (list_empty(&ctl->events)) {
1241 wait_queue_t wait;
1242 if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
1243 err = -EAGAIN;
1244 goto __end_lock;
1246 init_waitqueue_entry(&wait, current);
1247 add_wait_queue(&ctl->change_sleep, &wait);
1248 set_current_state(TASK_INTERRUPTIBLE);
1249 spin_unlock_irq(&ctl->read_lock);
1250 schedule();
1251 remove_wait_queue(&ctl->change_sleep, &wait);
1252 if (signal_pending(current))
1253 return -ERESTARTSYS;
1254 spin_lock_irq(&ctl->read_lock);
1256 kev = snd_kctl_event(ctl->events.next);
1257 ev.type = SNDRV_CTL_EVENT_ELEM;
1258 ev.data.elem.mask = kev->mask;
1259 ev.data.elem.id = kev->id;
1260 list_del(&kev->list);
1261 spin_unlock_irq(&ctl->read_lock);
1262 kfree(kev);
1263 if (copy_to_user(buffer, &ev, sizeof(struct snd_ctl_event))) {
1264 err = -EFAULT;
1265 goto __end;
1267 spin_lock_irq(&ctl->read_lock);
1268 buffer += sizeof(struct snd_ctl_event);
1269 count -= sizeof(struct snd_ctl_event);
1270 result += sizeof(struct snd_ctl_event);
1272 __end_lock:
1273 spin_unlock_irq(&ctl->read_lock);
1274 __end:
1275 return result > 0 ? result : err;
1278 static unsigned int snd_ctl_poll(struct file *file, poll_table * wait)
1280 unsigned int mask;
1281 struct snd_ctl_file *ctl;
1283 ctl = file->private_data;
1284 if (!ctl->subscribed)
1285 return 0;
1286 poll_wait(file, &ctl->change_sleep, wait);
1288 mask = 0;
1289 if (!list_empty(&ctl->events))
1290 mask |= POLLIN | POLLRDNORM;
1292 return mask;
1296 * register the device-specific control-ioctls.
1297 * called from each device manager like pcm.c, hwdep.c, etc.
1299 static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head *lists)
1301 struct snd_kctl_ioctl *pn;
1303 pn = kzalloc(sizeof(struct snd_kctl_ioctl), GFP_KERNEL);
1304 if (pn == NULL)
1305 return -ENOMEM;
1306 pn->fioctl = fcn;
1307 down_write(&snd_ioctl_rwsem);
1308 list_add_tail(&pn->list, lists);
1309 up_write(&snd_ioctl_rwsem);
1310 return 0;
1313 int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
1315 return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls);
1318 EXPORT_SYMBOL(snd_ctl_register_ioctl);
1320 #ifdef CONFIG_COMPAT
1321 int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn)
1323 return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls);
1326 EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
1327 #endif
1330 * de-register the device-specific control-ioctls.
1332 static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn,
1333 struct list_head *lists)
1335 struct snd_kctl_ioctl *p;
1337 if (snd_BUG_ON(!fcn))
1338 return -EINVAL;
1339 down_write(&snd_ioctl_rwsem);
1340 list_for_each_entry(p, lists, list) {
1341 if (p->fioctl == fcn) {
1342 list_del(&p->list);
1343 up_write(&snd_ioctl_rwsem);
1344 kfree(p);
1345 return 0;
1348 up_write(&snd_ioctl_rwsem);
1349 snd_BUG();
1350 return -EINVAL;
1353 int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
1355 return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls);
1358 EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
1360 #ifdef CONFIG_COMPAT
1361 int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn)
1363 return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls);
1366 EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
1367 #endif
1369 static int snd_ctl_fasync(int fd, struct file * file, int on)
1371 struct snd_ctl_file *ctl;
1373 ctl = file->private_data;
1374 return fasync_helper(fd, file, on, &ctl->fasync);
1378 * ioctl32 compat
1380 #ifdef CONFIG_COMPAT
1381 #include "control_compat.c"
1382 #else
1383 #define snd_ctl_ioctl_compat NULL
1384 #endif
1387 * INIT PART
1390 static const struct file_operations snd_ctl_f_ops =
1392 .owner = THIS_MODULE,
1393 .read = snd_ctl_read,
1394 .open = snd_ctl_open,
1395 .release = snd_ctl_release,
1396 .poll = snd_ctl_poll,
1397 .unlocked_ioctl = snd_ctl_ioctl,
1398 .compat_ioctl = snd_ctl_ioctl_compat,
1399 .fasync = snd_ctl_fasync,
1403 * registration of the control device
1405 static int snd_ctl_dev_register(struct snd_device *device)
1407 struct snd_card *card = device->device_data;
1408 int err, cardnum;
1409 char name[16];
1411 if (snd_BUG_ON(!card))
1412 return -ENXIO;
1413 cardnum = card->number;
1414 if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS))
1415 return -ENXIO;
1416 sprintf(name, "controlC%i", cardnum);
1417 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
1418 &snd_ctl_f_ops, card, name)) < 0)
1419 return err;
1420 return 0;
1424 * disconnection of the control device
1426 static int snd_ctl_dev_disconnect(struct snd_device *device)
1428 struct snd_card *card = device->device_data;
1429 struct snd_ctl_file *ctl;
1430 int err, cardnum;
1432 if (snd_BUG_ON(!card))
1433 return -ENXIO;
1434 cardnum = card->number;
1435 if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS))
1436 return -ENXIO;
1438 read_lock(&card->ctl_files_rwlock);
1439 list_for_each_entry(ctl, &card->ctl_files, list) {
1440 wake_up(&ctl->change_sleep);
1441 kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
1443 read_unlock(&card->ctl_files_rwlock);
1445 if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
1446 card, -1)) < 0)
1447 return err;
1448 return 0;
1452 * free all controls
1454 static int snd_ctl_dev_free(struct snd_device *device)
1456 struct snd_card *card = device->device_data;
1457 struct snd_kcontrol *control;
1459 down_write(&card->controls_rwsem);
1460 while (!list_empty(&card->controls)) {
1461 control = snd_kcontrol(card->controls.next);
1462 snd_ctl_remove(card, control);
1464 up_write(&card->controls_rwsem);
1465 return 0;
1469 * create control core:
1470 * called from init.c
1472 int snd_ctl_create(struct snd_card *card)
1474 static struct snd_device_ops ops = {
1475 .dev_free = snd_ctl_dev_free,
1476 .dev_register = snd_ctl_dev_register,
1477 .dev_disconnect = snd_ctl_dev_disconnect,
1480 if (snd_BUG_ON(!card))
1481 return -ENXIO;
1482 return snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
1486 * Frequently used control callbacks
1488 int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
1489 struct snd_ctl_elem_info *uinfo)
1491 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1492 uinfo->count = 1;
1493 uinfo->value.integer.min = 0;
1494 uinfo->value.integer.max = 1;
1495 return 0;
1498 EXPORT_SYMBOL(snd_ctl_boolean_mono_info);
1500 int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
1501 struct snd_ctl_elem_info *uinfo)
1503 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1504 uinfo->count = 2;
1505 uinfo->value.integer.min = 0;
1506 uinfo->value.integer.max = 1;
1507 return 0;
1510 EXPORT_SYMBOL(snd_ctl_boolean_stereo_info);