~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/core/control.c

Version: ~ [ linux-5.5-rc1 ] ~ [ linux-5.4.2 ] ~ [ linux-5.3.15 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.88 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.158 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.206 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.206 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.78 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  Routines for driver control interface
  3  *  Copyright (c) by Jaroslav Kysela <perex@perex.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 <linux/threads.h>
 23 #include <linux/interrupt.h>
 24 #include <linux/module.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 /* max number of user-defined controls */
 34 #define MAX_USER_CONTROLS       32
 35 #define MAX_CONTROL_COUNT       1028
 36 
 37 struct snd_kctl_ioctl {
 38         struct list_head list;          /* list of all ioctls */
 39         snd_kctl_ioctl_func_t fioctl;
 40 };
 41 
 42 static DECLARE_RWSEM(snd_ioctl_rwsem);
 43 static LIST_HEAD(snd_control_ioctls);
 44 #ifdef CONFIG_COMPAT
 45 static LIST_HEAD(snd_control_compat_ioctls);
 46 #endif
 47 
 48 static int snd_ctl_open(struct inode *inode, struct file *file)
 49 {
 50         unsigned long flags;
 51         struct snd_card *card;
 52         struct snd_ctl_file *ctl;
 53         int err;
 54 
 55         err = nonseekable_open(inode, file);
 56         if (err < 0)
 57                 return err;
 58 
 59         card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
 60         if (!card) {
 61                 err = -ENODEV;
 62                 goto __error1;
 63         }
 64         err = snd_card_file_add(card, file);
 65         if (err < 0) {
 66                 err = -ENODEV;
 67                 goto __error1;
 68         }
 69         if (!try_module_get(card->module)) {
 70                 err = -EFAULT;
 71                 goto __error2;
 72         }
 73         ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
 74         if (ctl == NULL) {
 75                 err = -ENOMEM;
 76                 goto __error;
 77         }
 78         INIT_LIST_HEAD(&ctl->events);
 79         init_waitqueue_head(&ctl->change_sleep);
 80         spin_lock_init(&ctl->read_lock);
 81         ctl->card = card;
 82         ctl->prefer_pcm_subdevice = -1;
 83         ctl->prefer_rawmidi_subdevice = -1;
 84         ctl->pid = get_pid(task_pid(current));
 85         file->private_data = ctl;
 86         write_lock_irqsave(&card->ctl_files_rwlock, flags);
 87         list_add_tail(&ctl->list, &card->ctl_files);
 88         write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
 89         snd_card_unref(card);
 90         return 0;
 91 
 92       __error:
 93         module_put(card->module);
 94       __error2:
 95         snd_card_file_remove(card, file);
 96       __error1:
 97         if (card)
 98                 snd_card_unref(card);
 99         return err;
100 }
101 
102 static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl)
103 {
104         unsigned long flags;
105         struct snd_kctl_event *cread;
106         
107         spin_lock_irqsave(&ctl->read_lock, flags);
108         while (!list_empty(&ctl->events)) {
109                 cread = snd_kctl_event(ctl->events.next);
110                 list_del(&cread->list);
111                 kfree(cread);
112         }
113         spin_unlock_irqrestore(&ctl->read_lock, flags);
114 }
115 
116 static int snd_ctl_release(struct inode *inode, struct file *file)
117 {
118         unsigned long flags;
119         struct snd_card *card;
120         struct snd_ctl_file *ctl;
121         struct snd_kcontrol *control;
122         unsigned int idx;
123 
124         ctl = file->private_data;
125         file->private_data = NULL;
126         card = ctl->card;
127         write_lock_irqsave(&card->ctl_files_rwlock, flags);
128         list_del(&ctl->list);
129         write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
130         down_write(&card->controls_rwsem);
131         list_for_each_entry(control, &card->controls, list)
132                 for (idx = 0; idx < control->count; idx++)
133                         if (control->vd[idx].owner == ctl)
134                                 control->vd[idx].owner = NULL;
135         up_write(&card->controls_rwsem);
136         snd_ctl_empty_read_queue(ctl);
137         put_pid(ctl->pid);
138         kfree(ctl);
139         module_put(card->module);
140         snd_card_file_remove(card, file);
141         return 0;
142 }
143 
144 void snd_ctl_notify(struct snd_card *card, unsigned int mask,
145                     struct snd_ctl_elem_id *id)
146 {
147         unsigned long flags;
148         struct snd_ctl_file *ctl;
149         struct snd_kctl_event *ev;
150         
151         if (snd_BUG_ON(!card || !id))
152                 return;
153         read_lock(&card->ctl_files_rwlock);
154 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
155         card->mixer_oss_change_count++;
156 #endif
157         list_for_each_entry(ctl, &card->ctl_files, list) {
158                 if (!ctl->subscribed)
159                         continue;
160                 spin_lock_irqsave(&ctl->read_lock, flags);
161                 list_for_each_entry(ev, &ctl->events, list) {
162                         if (ev->id.numid == id->numid) {
163                                 ev->mask |= mask;
164                                 goto _found;
165                         }
166                 }
167                 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
168                 if (ev) {
169                         ev->id = *id;
170                         ev->mask = mask;
171                         list_add_tail(&ev->list, &ctl->events);
172                 } else {
173                         snd_printk(KERN_ERR "No memory available to allocate event\n");
174                 }
175         _found:
176                 wake_up(&ctl->change_sleep);
177                 spin_unlock_irqrestore(&ctl->read_lock, flags);
178                 kill_fasync(&ctl->fasync, SIGIO, POLL_IN);
179         }
180         read_unlock(&card->ctl_files_rwlock);
181 }
182 
183 EXPORT_SYMBOL(snd_ctl_notify);
184 
185 /**
186  * snd_ctl_new - create a control instance from the template
187  * @control: the control template
188  * @access: the default control access
189  *
190  * Allocates a new struct snd_kcontrol instance and copies the given template 
191  * to the new instance. It does not copy volatile data (access).
192  *
193  * Returns the pointer of the new instance, or NULL on failure.
194  */
195 static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control,
196                                         unsigned int access)
197 {
198         struct snd_kcontrol *kctl;
199         unsigned int idx;
200         
201         if (snd_BUG_ON(!control || !control->count))
202                 return NULL;
203 
204         if (control->count > MAX_CONTROL_COUNT)
205                 return NULL;
206 
207         kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
208         if (kctl == NULL) {
209                 snd_printk(KERN_ERR "Cannot allocate control instance\n");
210                 return NULL;
211         }
212         *kctl = *control;
213         for (idx = 0; idx < kctl->count; idx++)
214                 kctl->vd[idx].access = access;
215         return kctl;
216 }
217 
218 /**
219  * snd_ctl_new1 - create a control instance from the template
220  * @ncontrol: the initialization record
221  * @private_data: the private data to set
222  *
223  * Allocates a new struct snd_kcontrol instance and initialize from the given 
224  * template.  When the access field of ncontrol is 0, it's assumed as
225  * READWRITE access. When the count field is 0, it's assumes as one.
226  *
227  * Returns the pointer of the newly generated instance, or NULL on failure.
228  */
229 struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
230                                   void *private_data)
231 {
232         struct snd_kcontrol kctl;
233         unsigned int access;
234         
235         if (snd_BUG_ON(!ncontrol || !ncontrol->info))
236                 return NULL;
237         memset(&kctl, 0, sizeof(kctl));
238         kctl.id.iface = ncontrol->iface;
239         kctl.id.device = ncontrol->device;
240         kctl.id.subdevice = ncontrol->subdevice;
241         if (ncontrol->name) {
242                 strlcpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name));
243                 if (strcmp(ncontrol->name, kctl.id.name) != 0)
244                         snd_printk(KERN_WARNING
245                                    "Control name '%s' truncated to '%s'\n",
246                                    ncontrol->name, kctl.id.name);
247         }
248         kctl.id.index = ncontrol->index;
249         kctl.count = ncontrol->count ? ncontrol->count : 1;
250         access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
251                  (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
252                                       SNDRV_CTL_ELEM_ACCESS_INACTIVE|
253                                       SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
254                                       SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND|
255                                       SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK));
256         kctl.info = ncontrol->info;
257         kctl.get = ncontrol->get;
258         kctl.put = ncontrol->put;
259         kctl.tlv.p = ncontrol->tlv.p;
260         kctl.private_value = ncontrol->private_value;
261         kctl.private_data = private_data;
262         return snd_ctl_new(&kctl, access);
263 }
264 
265 EXPORT_SYMBOL(snd_ctl_new1);
266 
267 /**
268  * snd_ctl_free_one - release the control instance
269  * @kcontrol: the control instance
270  *
271  * Releases the control instance created via snd_ctl_new()
272  * or snd_ctl_new1().
273  * Don't call this after the control was added to the card.
274  */
275 void snd_ctl_free_one(struct snd_kcontrol *kcontrol)
276 {
277         if (kcontrol) {
278                 if (kcontrol->private_free)
279                         kcontrol->private_free(kcontrol);
280                 kfree(kcontrol);
281         }
282 }
283 
284 EXPORT_SYMBOL(snd_ctl_free_one);
285 
286 static bool snd_ctl_remove_numid_conflict(struct snd_card *card,
287                                           unsigned int count)
288 {
289         struct snd_kcontrol *kctl;
290 
291         list_for_each_entry(kctl, &card->controls, list) {
292                 if (kctl->id.numid < card->last_numid + 1 + count &&
293                     kctl->id.numid + kctl->count > card->last_numid + 1) {
294                         card->last_numid = kctl->id.numid + kctl->count - 1;
295                         return true;
296                 }
297         }
298         return false;
299 }
300 
301 static int snd_ctl_find_hole(struct snd_card *card, unsigned int count)
302 {
303         unsigned int iter = 100000;
304 
305         while (snd_ctl_remove_numid_conflict(card, count)) {
306                 if (--iter == 0) {
307                         /* this situation is very unlikely */
308                         snd_printk(KERN_ERR "unable to allocate new control numid\n");
309                         return -ENOMEM;
310                 }
311         }
312         return 0;
313 }
314 
315 /**
316  * snd_ctl_add - add the control instance to the card
317  * @card: the card instance
318  * @kcontrol: the control instance to add
319  *
320  * Adds the control instance created via snd_ctl_new() or
321  * snd_ctl_new1() to the given card. Assigns also an unique
322  * numid used for fast search.
323  *
324  * Returns zero if successful, or a negative error code on failure.
325  *
326  * It frees automatically the control which cannot be added.
327  */
328 int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
329 {
330         struct snd_ctl_elem_id id;
331         unsigned int idx;
332         int err = -EINVAL;
333 
334         if (! kcontrol)
335                 return err;
336         if (snd_BUG_ON(!card || !kcontrol->info))
337                 goto error;
338         id = kcontrol->id;
339         down_write(&card->controls_rwsem);
340         if (snd_ctl_find_id(card, &id)) {
341                 up_write(&card->controls_rwsem);
342                 snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n",
343                                         id.iface,
344                                         id.device,
345                                         id.subdevice,
346                                         id.name,
347                                         id.index);
348                 err = -EBUSY;
349                 goto error;
350         }
351         if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
352                 up_write(&card->controls_rwsem);
353                 err = -ENOMEM;
354                 goto error;
355         }
356         list_add_tail(&kcontrol->list, &card->controls);
357         card->controls_count += kcontrol->count;
358         kcontrol->id.numid = card->last_numid + 1;
359         card->last_numid += kcontrol->count;
360         up_write(&card->controls_rwsem);
361         for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
362                 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
363         return 0;
364 
365  error:
366         snd_ctl_free_one(kcontrol);
367         return err;
368 }
369 
370 EXPORT_SYMBOL(snd_ctl_add);
371 
372 /**
373  * snd_ctl_replace - replace the control instance of the card
374  * @card: the card instance
375  * @kcontrol: the control instance to replace
376  * @add_on_replace: add the control if not already added
377  *
378  * Replaces the given control.  If the given control does not exist
379  * and the add_on_replace flag is set, the control is added.  If the
380  * control exists, it is destroyed first.
381  *
382  * Returns zero if successful, or a negative error code on failure.
383  *
384  * It frees automatically the control which cannot be added or replaced.
385  */
386 int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol,
387                     bool add_on_replace)
388 {
389         struct snd_ctl_elem_id id;
390         unsigned int idx;
391         struct snd_kcontrol *old;
392         int ret;
393 
394         if (!kcontrol)
395                 return -EINVAL;
396         if (snd_BUG_ON(!card || !kcontrol->info)) {
397                 ret = -EINVAL;
398                 goto error;
399         }
400         id = kcontrol->id;
401         down_write(&card->controls_rwsem);
402         old = snd_ctl_find_id(card, &id);
403         if (!old) {
404                 if (add_on_replace)
405                         goto add;
406                 up_write(&card->controls_rwsem);
407                 ret = -EINVAL;
408                 goto error;
409         }
410         ret = snd_ctl_remove(card, old);
411         if (ret < 0) {
412                 up_write(&card->controls_rwsem);
413                 goto error;
414         }
415 add:
416         if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
417                 up_write(&card->controls_rwsem);
418                 ret = -ENOMEM;
419                 goto error;
420         }
421         list_add_tail(&kcontrol->list, &card->controls);
422         card->controls_count += kcontrol->count;
423         kcontrol->id.numid = card->last_numid + 1;
424         card->last_numid += kcontrol->count;
425         up_write(&card->controls_rwsem);
426         for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
427                 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
428         return 0;
429 
430 error:
431         snd_ctl_free_one(kcontrol);
432         return ret;
433 }
434 EXPORT_SYMBOL(snd_ctl_replace);
435 
436 /**
437  * snd_ctl_remove - remove the control from the card and release it
438  * @card: the card instance
439  * @kcontrol: the control instance to remove
440  *
441  * Removes the control from the card and then releases the instance.
442  * You don't need to call snd_ctl_free_one(). You must be in
443  * the write lock - down_write(&card->controls_rwsem).
444  * 
445  * Returns 0 if successful, or a negative error code on failure.
446  */
447 int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
448 {
449         struct snd_ctl_elem_id id;
450         unsigned int idx;
451 
452         if (snd_BUG_ON(!card || !kcontrol))
453                 return -EINVAL;
454         list_del(&kcontrol->list);
455         card->controls_count -= kcontrol->count;
456         id = kcontrol->id;
457         for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
458                 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_REMOVE, &id);
459         snd_ctl_free_one(kcontrol);
460         return 0;
461 }
462 
463 EXPORT_SYMBOL(snd_ctl_remove);
464 
465 /**
466  * snd_ctl_remove_id - remove the control of the given id and release it
467  * @card: the card instance
468  * @id: the control id to remove
469  *
470  * Finds the control instance with the given id, removes it from the
471  * card list and releases it.
472  * 
473  * Returns 0 if successful, or a negative error code on failure.
474  */
475 int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
476 {
477         struct snd_kcontrol *kctl;
478         int ret;
479 
480         down_write(&card->controls_rwsem);
481         kctl = snd_ctl_find_id(card, id);
482         if (kctl == NULL) {
483                 up_write(&card->controls_rwsem);
484                 return -ENOENT;
485         }
486         ret = snd_ctl_remove(card, kctl);
487         up_write(&card->controls_rwsem);
488         return ret;
489 }
490 
491 EXPORT_SYMBOL(snd_ctl_remove_id);
492 
493 /**
494  * snd_ctl_remove_user_ctl - remove and release the unlocked user control
495  * @file: active control handle
496  * @id: the control id to remove
497  *
498  * Finds the control instance with the given id, removes it from the
499  * card list and releases it.
500  * 
501  * Returns 0 if successful, or a negative error code on failure.
502  */
503 static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file,
504                                    struct snd_ctl_elem_id *id)
505 {
506         struct snd_card *card = file->card;
507         struct snd_kcontrol *kctl;
508         int idx, ret;
509 
510         down_write(&card->controls_rwsem);
511         kctl = snd_ctl_find_id(card, id);
512         if (kctl == NULL) {
513                 ret = -ENOENT;
514                 goto error;
515         }
516         if (!(kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_USER)) {
517                 ret = -EINVAL;
518                 goto error;
519         }
520         for (idx = 0; idx < kctl->count; idx++)
521                 if (kctl->vd[idx].owner != NULL && kctl->vd[idx].owner != file) {
522                         ret = -EBUSY;
523                         goto error;
524                 }
525         ret = snd_ctl_remove(card, kctl);
526         if (ret < 0)
527                 goto error;
528         card->user_ctl_count--;
529 error:
530         up_write(&card->controls_rwsem);
531         return ret;
532 }
533 
534 /**
535  * snd_ctl_activate_id - activate/inactivate the control of the given id
536  * @card: the card instance
537  * @id: the control id to activate/inactivate
538  * @active: non-zero to activate
539  *
540  * Finds the control instance with the given id, and activate or
541  * inactivate the control together with notification, if changed.
542  *
543  * Returns 0 if unchanged, 1 if changed, or a negative error code on failure.
544  */
545 int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
546                         int active)
547 {
548         struct snd_kcontrol *kctl;
549         struct snd_kcontrol_volatile *vd;
550         unsigned int index_offset;
551         int ret;
552 
553         down_write(&card->controls_rwsem);
554         kctl = snd_ctl_find_id(card, id);
555         if (kctl == NULL) {
556                 ret = -ENOENT;
557                 goto unlock;
558         }
559         index_offset = snd_ctl_get_ioff(kctl, &kctl->id);
560         vd = &kctl->vd[index_offset];
561         ret = 0;
562         if (active) {
563                 if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE))
564                         goto unlock;
565                 vd->access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
566         } else {
567                 if (vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)
568                         goto unlock;
569                 vd->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
570         }
571         ret = 1;
572  unlock:
573         up_write(&card->controls_rwsem);
574         if (ret > 0)
575                 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, id);
576         return ret;
577 }
578 EXPORT_SYMBOL_GPL(snd_ctl_activate_id);
579 
580 /**
581  * snd_ctl_rename_id - replace the id of a control on the card
582  * @card: the card instance
583  * @src_id: the old id
584  * @dst_id: the new id
585  *
586  * Finds the control with the old id from the card, and replaces the
587  * id with the new one.
588  *
589  * Returns zero if successful, or a negative error code on failure.
590  */
591 int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
592                       struct snd_ctl_elem_id *dst_id)
593 {
594         struct snd_kcontrol *kctl;
595 
596         down_write(&card->controls_rwsem);
597         kctl = snd_ctl_find_id(card, src_id);
598         if (kctl == NULL) {
599                 up_write(&card->controls_rwsem);
600                 return -ENOENT;
601         }
602         kctl->id = *dst_id;
603         kctl->id.numid = card->last_numid + 1;
604         card->last_numid += kctl->count;
605         up_write(&card->controls_rwsem);
606         return 0;
607 }
608 
609 EXPORT_SYMBOL(snd_ctl_rename_id);
610 
611 /**
612  * snd_ctl_find_numid - find the control instance with the given number-id
613  * @card: the card instance
614  * @numid: the number-id to search
615  *
616  * Finds the control instance with the given number-id from the card.
617  *
618  * Returns the pointer of the instance if found, or NULL if not.
619  *
620  * The caller must down card->controls_rwsem before calling this function
621  * (if the race condition can happen).
622  */
623 struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid)
624 {
625         struct snd_kcontrol *kctl;
626 
627         if (snd_BUG_ON(!card || !numid))
628                 return NULL;
629         list_for_each_entry(kctl, &card->controls, list) {
630                 if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
631                         return kctl;
632         }
633         return NULL;
634 }
635 
636 EXPORT_SYMBOL(snd_ctl_find_numid);
637 
638 /**
639  * snd_ctl_find_id - find the control instance with the given id
640  * @card: the card instance
641  * @id: the id to search
642  *
643  * Finds the control instance with the given id from the card.
644  *
645  * Returns the pointer of the instance if found, or NULL if not.
646  *
647  * The caller must down card->controls_rwsem before calling this function
648  * (if the race condition can happen).
649  */
650 struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
651                                      struct snd_ctl_elem_id *id)
652 {
653         struct snd_kcontrol *kctl;
654 
655         if (snd_BUG_ON(!card || !id))
656                 return NULL;
657         if (id->numid != 0)
658                 return snd_ctl_find_numid(card, id->numid);
659         list_for_each_entry(kctl, &card->controls, list) {
660                 if (kctl->id.iface != id->iface)
661                         continue;
662                 if (kctl->id.device != id->device)
663                         continue;
664                 if (kctl->id.subdevice != id->subdevice)
665                         continue;
666                 if (strncmp(kctl->id.name, id->name, sizeof(kctl->id.name)))
667                         continue;
668                 if (kctl->id.index > id->index)
669                         continue;
670                 if (kctl->id.index + kctl->count <= id->index)
671                         continue;
672                 return kctl;
673         }
674         return NULL;
675 }
676 
677 EXPORT_SYMBOL(snd_ctl_find_id);
678 
679 static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
680                              unsigned int cmd, void __user *arg)
681 {
682         struct snd_ctl_card_info *info;
683 
684         info = kzalloc(sizeof(*info), GFP_KERNEL);
685         if (! info)
686                 return -ENOMEM;
687         down_read(&snd_ioctl_rwsem);
688         info->card = card->number;
689         strlcpy(info->id, card->id, sizeof(info->id));
690         strlcpy(info->driver, card->driver, sizeof(info->driver));
691         strlcpy(info->name, card->shortname, sizeof(info->name));
692         strlcpy(info->longname, card->longname, sizeof(info->longname));
693         strlcpy(info->mixername, card->mixername, sizeof(info->mixername));
694         strlcpy(info->components, card->components, sizeof(info->components));
695         up_read(&snd_ioctl_rwsem);
696         if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) {
697                 kfree(info);
698                 return -EFAULT;
699         }
700         kfree(info);
701         return 0;
702 }
703 
704 static int snd_ctl_elem_list(struct snd_card *card,
705                              struct snd_ctl_elem_list __user *_list)
706 {
707         struct list_head *plist;
708         struct snd_ctl_elem_list list;
709         struct snd_kcontrol *kctl;
710         struct snd_ctl_elem_id *dst, *id;
711         unsigned int offset, space, jidx;
712         
713         if (copy_from_user(&list, _list, sizeof(list)))
714                 return -EFAULT;
715         offset = list.offset;
716         space = list.space;
717         /* try limit maximum space */
718         if (space > 16384)
719                 return -ENOMEM;
720         if (space > 0) {
721                 /* allocate temporary buffer for atomic operation */
722                 dst = vmalloc(space * sizeof(struct snd_ctl_elem_id));
723                 if (dst == NULL)
724                         return -ENOMEM;
725                 down_read(&card->controls_rwsem);
726                 list.count = card->controls_count;
727                 plist = card->controls.next;
728                 while (plist != &card->controls) {
729                         if (offset == 0)
730                                 break;
731                         kctl = snd_kcontrol(plist);
732                         if (offset < kctl->count)
733                                 break;
734                         offset -= kctl->count;
735                         plist = plist->next;
736                 }
737                 list.used = 0;
738                 id = dst;
739                 while (space > 0 && plist != &card->controls) {
740                         kctl = snd_kcontrol(plist);
741                         for (jidx = offset; space > 0 && jidx < kctl->count; jidx++) {
742                                 snd_ctl_build_ioff(id, kctl, jidx);
743                                 id++;
744                                 space--;
745                                 list.used++;
746                         }
747                         plist = plist->next;
748                         offset = 0;
749                 }
750                 up_read(&card->controls_rwsem);
751                 if (list.used > 0 &&
752                     copy_to_user(list.pids, dst,
753                                  list.used * sizeof(struct snd_ctl_elem_id))) {
754                         vfree(dst);
755                         return -EFAULT;
756                 }
757                 vfree(dst);
758         } else {
759                 down_read(&card->controls_rwsem);
760                 list.count = card->controls_count;
761                 up_read(&card->controls_rwsem);
762         }
763         if (copy_to_user(_list, &list, sizeof(list)))
764                 return -EFAULT;
765         return 0;
766 }
767 
768 static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
769                              struct snd_ctl_elem_info *info)
770 {
771         struct snd_card *card = ctl->card;
772         struct snd_kcontrol *kctl;
773         struct snd_kcontrol_volatile *vd;
774         unsigned int index_offset;
775         int result;
776         
777         down_read(&card->controls_rwsem);
778         kctl = snd_ctl_find_id(card, &info->id);
779         if (kctl == NULL) {
780                 up_read(&card->controls_rwsem);
781                 return -ENOENT;
782         }
783 #ifdef CONFIG_SND_DEBUG
784         info->access = 0;
785 #endif
786         result = kctl->info(kctl, info);
787         if (result >= 0) {
788                 snd_BUG_ON(info->access);
789                 index_offset = snd_ctl_get_ioff(kctl, &info->id);
790                 vd = &kctl->vd[index_offset];
791                 snd_ctl_build_ioff(&info->id, kctl, index_offset);
792                 info->access = vd->access;
793                 if (vd->owner) {
794                         info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK;
795                         if (vd->owner == ctl)
796                                 info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER;
797                         info->owner = pid_vnr(vd->owner->pid);
798                 } else {
799                         info->owner = -1;
800                 }
801         }
802         up_read(&card->controls_rwsem);
803         return result;
804 }
805 
806 static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
807                                   struct snd_ctl_elem_info __user *_info)
808 {
809         struct snd_ctl_elem_info info;
810         int result;
811 
812         if (copy_from_user(&info, _info, sizeof(info)))
813                 return -EFAULT;
814         snd_power_lock(ctl->card);
815         result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
816         if (result >= 0)
817                 result = snd_ctl_elem_info(ctl, &info);
818         snd_power_unlock(ctl->card);
819         if (result >= 0)
820                 if (copy_to_user(_info, &info, sizeof(info)))
821                         return -EFAULT;
822         return result;
823 }
824 
825 static int snd_ctl_elem_read(struct snd_card *card,
826                              struct snd_ctl_elem_value *control)
827 {
828         struct snd_kcontrol *kctl;
829         struct snd_kcontrol_volatile *vd;
830         unsigned int index_offset;
831         int result;
832 
833         down_read(&card->controls_rwsem);
834         kctl = snd_ctl_find_id(card, &control->id);
835         if (kctl == NULL) {
836                 result = -ENOENT;
837         } else {
838                 index_offset = snd_ctl_get_ioff(kctl, &control->id);
839                 vd = &kctl->vd[index_offset];
840                 if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) &&
841                     kctl->get != NULL) {
842                         snd_ctl_build_ioff(&control->id, kctl, index_offset);
843                         result = kctl->get(kctl, control);
844                 } else
845                         result = -EPERM;
846         }
847         up_read(&card->controls_rwsem);
848         return result;
849 }
850 
851 static int snd_ctl_elem_read_user(struct snd_card *card,
852                                   struct snd_ctl_elem_value __user *_control)
853 {
854         struct snd_ctl_elem_value *control;
855         int result;
856 
857         control = memdup_user(_control, sizeof(*control));
858         if (IS_ERR(control))
859                 return PTR_ERR(control);
860 
861         snd_power_lock(card);
862         result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
863         if (result >= 0)
864                 result = snd_ctl_elem_read(card, control);
865         snd_power_unlock(card);
866         if (result >= 0)
867                 if (copy_to_user(_control, control, sizeof(*control)))
868                         result = -EFAULT;
869         kfree(control);
870         return result;
871 }
872 
873 static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
874                               struct snd_ctl_elem_value *control)
875 {
876         struct snd_kcontrol *kctl;
877         struct snd_kcontrol_volatile *vd;
878         unsigned int index_offset;
879         int result;
880 
881         down_read(&card->controls_rwsem);
882         kctl = snd_ctl_find_id(card, &control->id);
883         if (kctl == NULL) {
884                 result = -ENOENT;
885         } else {
886                 index_offset = snd_ctl_get_ioff(kctl, &control->id);
887                 vd = &kctl->vd[index_offset];
888                 if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
889                     kctl->put == NULL ||
890                     (file && vd->owner && vd->owner != file)) {
891                         result = -EPERM;
892                 } else {
893                         snd_ctl_build_ioff(&control->id, kctl, index_offset);
894                         result = kctl->put(kctl, control);
895                 }
896                 if (result > 0) {
897                         up_read(&card->controls_rwsem);
898                         snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
899                                        &control->id);
900                         return 0;
901                 }
902         }
903         up_read(&card->controls_rwsem);
904         return result;
905 }
906 
907 static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
908                                    struct snd_ctl_elem_value __user *_control)
909 {
910         struct snd_ctl_elem_value *control;
911         struct snd_card *card;
912         int result;
913 
914         control = memdup_user(_control, sizeof(*control));
915         if (IS_ERR(control))
916                 return PTR_ERR(control);
917 
918         card = file->card;
919         snd_power_lock(card);
920         result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
921         if (result >= 0)
922                 result = snd_ctl_elem_write(card, file, control);
923         snd_power_unlock(card);
924         if (result >= 0)
925                 if (copy_to_user(_control, control, sizeof(*control)))
926                         result = -EFAULT;
927         kfree(control);
928         return result;
929 }
930 
931 static int snd_ctl_elem_lock(struct snd_ctl_file *file,
932                              struct snd_ctl_elem_id __user *_id)
933 {
934         struct snd_card *card = file->card;
935         struct snd_ctl_elem_id id;
936         struct snd_kcontrol *kctl;
937         struct snd_kcontrol_volatile *vd;
938         int result;
939         
940         if (copy_from_user(&id, _id, sizeof(id)))
941                 return -EFAULT;
942         down_write(&card->controls_rwsem);
943         kctl = snd_ctl_find_id(card, &id);
944         if (kctl == NULL) {
945                 result = -ENOENT;
946         } else {
947                 vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
948                 if (vd->owner != NULL)
949                         result = -EBUSY;
950                 else {
951                         vd->owner = file;
952                         result = 0;
953                 }
954         }
955         up_write(&card->controls_rwsem);
956         return result;
957 }
958 
959 static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
960                                struct snd_ctl_elem_id __user *_id)
961 {
962         struct snd_card *card = file->card;
963         struct snd_ctl_elem_id id;
964         struct snd_kcontrol *kctl;
965         struct snd_kcontrol_volatile *vd;
966         int result;
967         
968         if (copy_from_user(&id, _id, sizeof(id)))
969                 return -EFAULT;
970         down_write(&card->controls_rwsem);
971         kctl = snd_ctl_find_id(card, &id);
972         if (kctl == NULL) {
973                 result = -ENOENT;
974         } else {
975                 vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
976                 if (vd->owner == NULL)
977                         result = -EINVAL;
978                 else if (vd->owner != file)
979                         result = -EPERM;
980                 else {
981                         vd->owner = NULL;
982                         result = 0;
983                 }
984         }
985         up_write(&card->controls_rwsem);
986         return result;
987 }
988 
989 struct user_element {
990         struct snd_ctl_elem_info info;
991         void *elem_data;                /* element data */
992         unsigned long elem_data_size;   /* size of element data in bytes */
993         void *tlv_data;                 /* TLV data */
994         unsigned long tlv_data_size;    /* TLV data size */
995         void *priv_data;                /* private data (like strings for enumerated type) */
996 };
997 
998 static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
999                                   struct snd_ctl_elem_info *uinfo)
1000 {
1001         struct user_element *ue = kcontrol->private_data;
1002 
1003         *uinfo = ue->info;
1004         return 0;
1005 }
1006 
1007 static int snd_ctl_elem_user_enum_info(struct snd_kcontrol *kcontrol,
1008                                        struct snd_ctl_elem_info *uinfo)
1009 {
1010         struct user_element *ue = kcontrol->private_data;
1011         const char *names;
1012         unsigned int item;
1013 
1014         item = uinfo->value.enumerated.item;
1015 
1016         *uinfo = ue->info;
1017 
1018         item = min(item, uinfo->value.enumerated.items - 1);
1019         uinfo->value.enumerated.item = item;
1020 
1021         names = ue->priv_data;
1022         for (; item > 0; --item)
1023                 names += strlen(names) + 1;
1024         strcpy(uinfo->value.enumerated.name, names);
1025 
1026         return 0;
1027 }
1028 
1029 static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
1030                                  struct snd_ctl_elem_value *ucontrol)
1031 {
1032         struct user_element *ue = kcontrol->private_data;
1033 
1034         memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size);
1035         return 0;
1036 }
1037 
1038 static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
1039                                  struct snd_ctl_elem_value *ucontrol)
1040 {
1041         int change;
1042         struct user_element *ue = kcontrol->private_data;
1043         
1044         change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0;
1045         if (change)
1046                 memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
1047         return change;
1048 }
1049 
1050 static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
1051                                  int op_flag,
1052                                  unsigned int size,
1053                                  unsigned int __user *tlv)
1054 {
1055         struct user_element *ue = kcontrol->private_data;
1056         int change = 0;
1057         void *new_data;
1058 
1059         if (op_flag > 0) {
1060                 if (size > 1024 * 128)  /* sane value */
1061                         return -EINVAL;
1062 
1063                 new_data = memdup_user(tlv, size);
1064                 if (IS_ERR(new_data))
1065                         return PTR_ERR(new_data);
1066                 change = ue->tlv_data_size != size;
1067                 if (!change)
1068                         change = memcmp(ue->tlv_data, new_data, size);
1069                 kfree(ue->tlv_data);
1070                 ue->tlv_data = new_data;
1071                 ue->tlv_data_size = size;
1072         } else {
1073                 if (! ue->tlv_data_size || ! ue->tlv_data)
1074                         return -ENXIO;
1075                 if (size < ue->tlv_data_size)
1076                         return -ENOSPC;
1077                 if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
1078                         return -EFAULT;
1079         }
1080         return change;
1081 }
1082 
1083 static int snd_ctl_elem_init_enum_names(struct user_element *ue)
1084 {
1085         char *names, *p;
1086         size_t buf_len, name_len;
1087         unsigned int i;
1088         const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr;
1089 
1090         if (ue->info.value.enumerated.names_length > 64 * 1024)
1091                 return -EINVAL;
1092 
1093         names = memdup_user((const void __user *)user_ptrval,
1094                 ue->info.value.enumerated.names_length);
1095         if (IS_ERR(names))
1096                 return PTR_ERR(names);
1097 
1098         /* check that there are enough valid names */
1099         buf_len = ue->info.value.enumerated.names_length;
1100         p = names;
1101         for (i = 0; i < ue->info.value.enumerated.items; ++i) {
1102                 name_len = strnlen(p, buf_len);
1103                 if (name_len == 0 || name_len >= 64 || name_len == buf_len) {
1104                         kfree(names);
1105                         return -EINVAL;
1106                 }
1107                 p += name_len + 1;
1108                 buf_len -= name_len + 1;
1109         }
1110 
1111         ue->priv_data = names;
1112         ue->info.value.enumerated.names_ptr = 0;
1113 
1114         return 0;
1115 }
1116 
1117 static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol)
1118 {
1119         struct user_element *ue = kcontrol->private_data;
1120 
1121         kfree(ue->tlv_data);
1122         kfree(ue->priv_data);
1123         kfree(ue);
1124 }
1125 
1126 static int snd_ctl_elem_add(struct snd_ctl_file *file,
1127                             struct snd_ctl_elem_info *info, int replace)
1128 {
1129         struct snd_card *card = file->card;
1130         struct snd_kcontrol kctl, *_kctl;
1131         unsigned int access;
1132         long private_size;
1133         struct user_element *ue;
1134         int idx, err;
1135 
1136         if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
1137                 return -ENOMEM;
1138         if (info->count < 1)
1139                 return -EINVAL;
1140         access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
1141                 (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
1142                                  SNDRV_CTL_ELEM_ACCESS_INACTIVE|
1143                                  SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE));
1144         info->id.numid = 0;
1145         memset(&kctl, 0, sizeof(kctl));
1146         down_write(&card->controls_rwsem);
1147         _kctl = snd_ctl_find_id(card, &info->id);
1148         err = 0;
1149         if (_kctl) {
1150                 if (replace)
1151                         err = snd_ctl_remove(card, _kctl);
1152                 else
1153                         err = -EBUSY;
1154         } else {
1155                 if (replace)
1156                         err = -ENOENT;
1157         }
1158         up_write(&card->controls_rwsem);
1159         if (err < 0)
1160                 return err;
1161         memcpy(&kctl.id, &info->id, sizeof(info->id));
1162         kctl.count = info->owner ? info->owner : 1;
1163         access |= SNDRV_CTL_ELEM_ACCESS_USER;
1164         if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED)
1165                 kctl.info = snd_ctl_elem_user_enum_info;
1166         else
1167                 kctl.info = snd_ctl_elem_user_info;
1168         if (access & SNDRV_CTL_ELEM_ACCESS_READ)
1169                 kctl.get = snd_ctl_elem_user_get;
1170         if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
1171                 kctl.put = snd_ctl_elem_user_put;
1172         if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) {
1173                 kctl.tlv.c = snd_ctl_elem_user_tlv;
1174                 access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1175         }
1176         switch (info->type) {
1177         case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
1178         case SNDRV_CTL_ELEM_TYPE_INTEGER:
1179                 private_size = sizeof(long);
1180                 if (info->count > 128)
1181                         return -EINVAL;
1182                 break;
1183         case SNDRV_CTL_ELEM_TYPE_INTEGER64:
1184                 private_size = sizeof(long long);
1185                 if (info->count > 64)
1186                         return -EINVAL;
1187                 break;
1188         case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
1189                 private_size = sizeof(unsigned int);
1190                 if (info->count > 128 || info->value.enumerated.items == 0)
1191                         return -EINVAL;
1192                 break;
1193         case SNDRV_CTL_ELEM_TYPE_BYTES:
1194                 private_size = sizeof(unsigned char);
1195                 if (info->count > 512)
1196                         return -EINVAL;
1197                 break;
1198         case SNDRV_CTL_ELEM_TYPE_IEC958:
1199                 private_size = sizeof(struct snd_aes_iec958);
1200                 if (info->count != 1)
1201                         return -EINVAL;
1202                 break;
1203         default:
1204                 return -EINVAL;
1205         }
1206         private_size *= info->count;
1207         ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL);
1208         if (ue == NULL)
1209                 return -ENOMEM;
1210         ue->info = *info;
1211         ue->info.access = 0;
1212         ue->elem_data = (char *)ue + sizeof(*ue);
1213         ue->elem_data_size = private_size;
1214         if (ue->info.type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
1215                 err = snd_ctl_elem_init_enum_names(ue);
1216                 if (err < 0) {
1217                         kfree(ue);
1218                         return err;
1219                 }
1220         }
1221         kctl.private_free = snd_ctl_elem_user_free;
1222         _kctl = snd_ctl_new(&kctl, access);
1223         if (_kctl == NULL) {
1224                 kfree(ue->priv_data);
1225                 kfree(ue);
1226                 return -ENOMEM;
1227         }
1228         _kctl->private_data = ue;
1229         for (idx = 0; idx < _kctl->count; idx++)
1230                 _kctl->vd[idx].owner = file;
1231         err = snd_ctl_add(card, _kctl);
1232         if (err < 0)
1233                 return err;
1234 
1235         down_write(&card->controls_rwsem);
1236         card->user_ctl_count++;
1237         up_write(&card->controls_rwsem);
1238 
1239         return 0;
1240 }
1241 
1242 static int snd_ctl_elem_add_user(struct snd_ctl_file *file,
1243                                  struct snd_ctl_elem_info __user *_info, int replace)
1244 {
1245         struct snd_ctl_elem_info info;
1246         if (copy_from_user(&info, _info, sizeof(info)))
1247                 return -EFAULT;
1248         return snd_ctl_elem_add(file, &info, replace);
1249 }
1250 
1251 static int snd_ctl_elem_remove(struct snd_ctl_file *file,
1252                                struct snd_ctl_elem_id __user *_id)
1253 {
1254         struct snd_ctl_elem_id id;
1255 
1256         if (copy_from_user(&id, _id, sizeof(id)))
1257                 return -EFAULT;
1258         return snd_ctl_remove_user_ctl(file, &id);
1259 }
1260 
1261 static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
1262 {
1263         int subscribe;
1264         if (get_user(subscribe, ptr))
1265                 return -EFAULT;
1266         if (subscribe < 0) {
1267                 subscribe = file->subscribed;
1268                 if (put_user(subscribe, ptr))
1269                         return -EFAULT;
1270                 return 0;
1271         }
1272         if (subscribe) {
1273                 file->subscribed = 1;
1274                 return 0;
1275         } else if (file->subscribed) {
1276                 snd_ctl_empty_read_queue(file);
1277                 file->subscribed = 0;
1278         }
1279         return 0;
1280 }
1281 
1282 static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1283                              struct snd_ctl_tlv __user *_tlv,
1284                              int op_flag)
1285 {
1286         struct snd_card *card = file->card;
1287         struct snd_ctl_tlv tlv;
1288         struct snd_kcontrol *kctl;
1289         struct snd_kcontrol_volatile *vd;
1290         unsigned int len;
1291         int err = 0;
1292 
1293         if (copy_from_user(&tlv, _tlv, sizeof(tlv)))
1294                 return -EFAULT;
1295         if (tlv.length < sizeof(unsigned int) * 2)
1296                 return -EINVAL;
1297         down_read(&card->controls_rwsem);
1298         kctl = snd_ctl_find_numid(card, tlv.numid);
1299         if (kctl == NULL) {
1300                 err = -ENOENT;
1301                 goto __kctl_end;
1302         }
1303         if (kctl->tlv.p == NULL) {
1304                 err = -ENXIO;
1305                 goto __kctl_end;
1306         }
1307         vd = &kctl->vd[tlv.numid - kctl->id.numid];
1308         if ((op_flag == 0 && (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) == 0) ||
1309             (op_flag > 0 && (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) == 0) ||
1310             (op_flag < 0 && (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND) == 0)) {
1311                 err = -ENXIO;
1312                 goto __kctl_end;
1313         }
1314         if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
1315                 if (vd->owner != NULL && vd->owner != file) {
1316                         err = -EPERM;
1317                         goto __kctl_end;
1318                 }
1319                 err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
1320                 if (err > 0) {
1321                         up_read(&card->controls_rwsem);
1322                         snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
1323                         return 0;
1324                 }
1325         } else {
1326                 if (op_flag) {
1327                         err = -ENXIO;
1328                         goto __kctl_end;
1329                 }
1330                 len = kctl->tlv.p[1] + 2 * sizeof(unsigned int);
1331                 if (tlv.length < len) {
1332                         err = -ENOMEM;
1333                         goto __kctl_end;
1334                 }
1335                 if (copy_to_user(_tlv->tlv, kctl->tlv.p, len))
1336                         err = -EFAULT;
1337         }
1338       __kctl_end:
1339         up_read(&card->controls_rwsem);
1340         return err;
1341 }
1342 
1343 static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1344 {
1345         struct snd_ctl_file *ctl;
1346         struct snd_card *card;
1347         struct snd_kctl_ioctl *p;
1348         void __user *argp = (void __user *)arg;
1349         int __user *ip = argp;
1350         int err;
1351 
1352         ctl = file->private_data;
1353         card = ctl->card;
1354         if (snd_BUG_ON(!card))
1355                 return -ENXIO;
1356         switch (cmd) {
1357         case SNDRV_CTL_IOCTL_PVERSION:
1358                 return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0;
1359         case SNDRV_CTL_IOCTL_CARD_INFO:
1360                 return snd_ctl_card_info(card, ctl, cmd, argp);
1361         case SNDRV_CTL_IOCTL_ELEM_LIST:
1362                 return snd_ctl_elem_list(card, argp);
1363         case SNDRV_CTL_IOCTL_ELEM_INFO:
1364                 return snd_ctl_elem_info_user(ctl, argp);
1365         case SNDRV_CTL_IOCTL_ELEM_READ:
1366                 return snd_ctl_elem_read_user(card, argp);
1367         case SNDRV_CTL_IOCTL_ELEM_WRITE:
1368                 return snd_ctl_elem_write_user(ctl, argp);
1369         case SNDRV_CTL_IOCTL_ELEM_LOCK:
1370                 return snd_ctl_elem_lock(ctl, argp);
1371         case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
1372                 return snd_ctl_elem_unlock(ctl, argp);
1373         case SNDRV_CTL_IOCTL_ELEM_ADD:
1374                 return snd_ctl_elem_add_user(ctl, argp, 0);
1375         case SNDRV_CTL_IOCTL_ELEM_REPLACE:
1376                 return snd_ctl_elem_add_user(ctl, argp, 1);
1377         case SNDRV_CTL_IOCTL_ELEM_REMOVE:
1378                 return snd_ctl_elem_remove(ctl, argp);
1379         case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
1380                 return snd_ctl_subscribe_events(ctl, ip);
1381         case SNDRV_CTL_IOCTL_TLV_READ:
1382                 return snd_ctl_tlv_ioctl(ctl, argp, 0);
1383         case SNDRV_CTL_IOCTL_TLV_WRITE:
1384                 return snd_ctl_tlv_ioctl(ctl, argp, 1);
1385         case SNDRV_CTL_IOCTL_TLV_COMMAND:
1386                 return snd_ctl_tlv_ioctl(ctl, argp, -1);
1387         case SNDRV_CTL_IOCTL_POWER:
1388                 return -ENOPROTOOPT;
1389         case SNDRV_CTL_IOCTL_POWER_STATE:
1390 #ifdef CONFIG_PM
1391                 return put_user(card->power_state, ip) ? -EFAULT : 0;
1392 #else
1393                 return put_user(SNDRV_CTL_POWER_D0, ip) ? -EFAULT : 0;
1394 #endif
1395         }
1396         down_read(&snd_ioctl_rwsem);
1397         list_for_each_entry(p, &snd_control_ioctls, list) {
1398                 err = p->fioctl(card, ctl, cmd, arg);
1399                 if (err != -ENOIOCTLCMD) {
1400                         up_read(&snd_ioctl_rwsem);
1401                         return err;
1402                 }
1403         }
1404         up_read(&snd_ioctl_rwsem);
1405         snd_printdd("unknown ioctl = 0x%x\n", cmd);
1406         return -ENOTTY;
1407 }
1408 
1409 static ssize_t snd_ctl_read(struct file *file, char __user *buffer,
1410                             size_t count, loff_t * offset)
1411 {
1412         struct snd_ctl_file *ctl;
1413         int err = 0;
1414         ssize_t result = 0;
1415 
1416         ctl = file->private_data;
1417         if (snd_BUG_ON(!ctl || !ctl->card))
1418                 return -ENXIO;
1419         if (!ctl->subscribed)
1420                 return -EBADFD;
1421         if (count < sizeof(struct snd_ctl_event))
1422                 return -EINVAL;
1423         spin_lock_irq(&ctl->read_lock);
1424         while (count >= sizeof(struct snd_ctl_event)) {
1425                 struct snd_ctl_event ev;
1426                 struct snd_kctl_event *kev;
1427                 while (list_empty(&ctl->events)) {
1428                         wait_queue_t wait;
1429                         if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
1430                                 err = -EAGAIN;
1431                                 goto __end_lock;
1432                         }
1433                         init_waitqueue_entry(&wait, current);
1434                         add_wait_queue(&ctl->change_sleep, &wait);
1435                         set_current_state(TASK_INTERRUPTIBLE);
1436                         spin_unlock_irq(&ctl->read_lock);
1437                         schedule();
1438                         remove_wait_queue(&ctl->change_sleep, &wait);
1439                         if (ctl->card->shutdown)
1440                                 return -ENODEV;
1441                         if (signal_pending(current))
1442                                 return -ERESTARTSYS;
1443                         spin_lock_irq(&ctl->read_lock);
1444                 }
1445                 kev = snd_kctl_event(ctl->events.next);
1446                 ev.type = SNDRV_CTL_EVENT_ELEM;
1447                 ev.data.elem.mask = kev->mask;
1448                 ev.data.elem.id = kev->id;
1449                 list_del(&kev->list);
1450                 spin_unlock_irq(&ctl->read_lock);
1451                 kfree(kev);
1452                 if (copy_to_user(buffer, &ev, sizeof(struct snd_ctl_event))) {
1453                         err = -EFAULT;
1454                         goto __end;
1455                 }
1456                 spin_lock_irq(&ctl->read_lock);
1457                 buffer += sizeof(struct snd_ctl_event);
1458                 count -= sizeof(struct snd_ctl_event);
1459                 result += sizeof(struct snd_ctl_event);
1460         }
1461       __end_lock:
1462         spin_unlock_irq(&ctl->read_lock);
1463       __end:
1464         return result > 0 ? result : err;
1465 }
1466 
1467 static unsigned int snd_ctl_poll(struct file *file, poll_table * wait)
1468 {
1469         unsigned int mask;
1470         struct snd_ctl_file *ctl;
1471 
1472         ctl = file->private_data;
1473         if (!ctl->subscribed)
1474                 return 0;
1475         poll_wait(file, &ctl->change_sleep, wait);
1476 
1477         mask = 0;
1478         if (!list_empty(&ctl->events))
1479                 mask |= POLLIN | POLLRDNORM;
1480 
1481         return mask;
1482 }
1483 
1484 /*
1485  * register the device-specific control-ioctls.
1486  * called from each device manager like pcm.c, hwdep.c, etc.
1487  */
1488 static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head *lists)
1489 {
1490         struct snd_kctl_ioctl *pn;
1491 
1492         pn = kzalloc(sizeof(struct snd_kctl_ioctl), GFP_KERNEL);
1493         if (pn == NULL)
1494                 return -ENOMEM;
1495         pn->fioctl = fcn;
1496         down_write(&snd_ioctl_rwsem);
1497         list_add_tail(&pn->list, lists);
1498         up_write(&snd_ioctl_rwsem);
1499         return 0;
1500 }
1501 
1502 int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
1503 {
1504         return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls);
1505 }
1506 
1507 EXPORT_SYMBOL(snd_ctl_register_ioctl);
1508 
1509 #ifdef CONFIG_COMPAT
1510 int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn)
1511 {
1512         return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls);
1513 }
1514 
1515 EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
1516 #endif
1517 
1518 /*
1519  * de-register the device-specific control-ioctls.
1520  */
1521 static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn,
1522                                      struct list_head *lists)
1523 {
1524         struct snd_kctl_ioctl *p;
1525 
1526         if (snd_BUG_ON(!fcn))
1527                 return -EINVAL;
1528         down_write(&snd_ioctl_rwsem);
1529         list_for_each_entry(p, lists, list) {
1530                 if (p->fioctl == fcn) {
1531                         list_del(&p->list);
1532                         up_write(&snd_ioctl_rwsem);
1533                         kfree(p);
1534                         return 0;
1535                 }
1536         }
1537         up_write(&snd_ioctl_rwsem);
1538         snd_BUG();
1539         return -EINVAL;
1540 }
1541 
1542 int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
1543 {
1544         return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls);
1545 }
1546 
1547 EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
1548 
1549 #ifdef CONFIG_COMPAT
1550 int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn)
1551 {
1552         return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls);
1553 }
1554 
1555 EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
1556 #endif
1557 
1558 static int snd_ctl_fasync(int fd, struct file * file, int on)
1559 {
1560         struct snd_ctl_file *ctl;
1561 
1562         ctl = file->private_data;
1563         return fasync_helper(fd, file, on, &ctl->fasync);
1564 }
1565 
1566 /*
1567  * ioctl32 compat
1568  */
1569 #ifdef CONFIG_COMPAT
1570 #include "control_compat.c"
1571 #else
1572 #define snd_ctl_ioctl_compat    NULL
1573 #endif
1574 
1575 /*
1576  *  INIT PART
1577  */
1578 
1579 static const struct file_operations snd_ctl_f_ops =
1580 {
1581         .owner =        THIS_MODULE,
1582         .read =         snd_ctl_read,
1583         .open =         snd_ctl_open,
1584         .release =      snd_ctl_release,
1585         .llseek =       no_llseek,
1586         .poll =         snd_ctl_poll,
1587         .unlocked_ioctl =       snd_ctl_ioctl,
1588         .compat_ioctl = snd_ctl_ioctl_compat,
1589         .fasync =       snd_ctl_fasync,
1590 };
1591 
1592 /*
1593  * registration of the control device
1594  */
1595 static int snd_ctl_dev_register(struct snd_device *device)
1596 {
1597         struct snd_card *card = device->device_data;
1598         int err, cardnum;
1599         char name[16];
1600 
1601         if (snd_BUG_ON(!card))
1602                 return -ENXIO;
1603         cardnum = card->number;
1604         if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS))
1605                 return -ENXIO;
1606         sprintf(name, "controlC%i", cardnum);
1607         if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
1608                                        &snd_ctl_f_ops, card, name)) < 0)
1609                 return err;
1610         return 0;
1611 }
1612 
1613 /*
1614  * disconnection of the control device
1615  */
1616 static int snd_ctl_dev_disconnect(struct snd_device *device)
1617 {
1618         struct snd_card *card = device->device_data;
1619         struct snd_ctl_file *ctl;
1620         int err, cardnum;
1621 
1622         if (snd_BUG_ON(!card))
1623                 return -ENXIO;
1624         cardnum = card->number;
1625         if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS))
1626                 return -ENXIO;
1627 
1628         read_lock(&card->ctl_files_rwlock);
1629         list_for_each_entry(ctl, &card->ctl_files, list) {
1630                 wake_up(&ctl->change_sleep);
1631                 kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
1632         }
1633         read_unlock(&card->ctl_files_rwlock);
1634 
1635         if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
1636                                          card, -1)) < 0)
1637                 return err;
1638         return 0;
1639 }
1640 
1641 /*
1642  * free all controls
1643  */
1644 static int snd_ctl_dev_free(struct snd_device *device)
1645 {
1646         struct snd_card *card = device->device_data;
1647         struct snd_kcontrol *control;
1648 
1649         down_write(&card->controls_rwsem);
1650         while (!list_empty(&card->controls)) {
1651                 control = snd_kcontrol(card->controls.next);
1652                 snd_ctl_remove(card, control);
1653         }
1654         up_write(&card->controls_rwsem);
1655         return 0;
1656 }
1657 
1658 /*
1659  * create control core:
1660  * called from init.c
1661  */
1662 int snd_ctl_create(struct snd_card *card)
1663 {
1664         static struct snd_device_ops ops = {
1665                 .dev_free = snd_ctl_dev_free,
1666                 .dev_register = snd_ctl_dev_register,
1667                 .dev_disconnect = snd_ctl_dev_disconnect,
1668         };
1669 
1670         if (snd_BUG_ON(!card))
1671                 return -ENXIO;
1672         return snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
1673 }
1674 
1675 /*
1676  * Frequently used control callbacks/helpers
1677  */
1678 int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
1679                               struct snd_ctl_elem_info *uinfo)
1680 {
1681         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1682         uinfo->count = 1;
1683         uinfo->value.integer.min = 0;
1684         uinfo->value.integer.max = 1;
1685         return 0;
1686 }
1687 
1688 EXPORT_SYMBOL(snd_ctl_boolean_mono_info);
1689 
1690 int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
1691                                 struct snd_ctl_elem_info *uinfo)
1692 {
1693         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1694         uinfo->count = 2;
1695         uinfo->value.integer.min = 0;
1696         uinfo->value.integer.max = 1;
1697         return 0;
1698 }
1699 
1700 EXPORT_SYMBOL(snd_ctl_boolean_stereo_info);
1701 
1702 /**
1703  * snd_ctl_enum_info - fills the info structure for an enumerated control
1704  * @info: the structure to be filled
1705  * @channels: the number of the control's channels; often one
1706  * @items: the number of control values; also the size of @names
1707  * @names: an array containing the names of all control values
1708  *
1709  * Sets all required fields in @info to their appropriate values.
1710  * If the control's accessibility is not the default (readable and writable),
1711  * the caller has to fill @info->access.
1712  */
1713 int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels,
1714                       unsigned int items, const char *const names[])
1715 {
1716         info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1717         info->count = channels;
1718         info->value.enumerated.items = items;
1719         if (info->value.enumerated.item >= items)
1720                 info->value.enumerated.item = items - 1;
1721         strlcpy(info->value.enumerated.name,
1722                 names[info->value.enumerated.item],
1723                 sizeof(info->value.enumerated.name));
1724         return 0;
1725 }
1726 EXPORT_SYMBOL(snd_ctl_enum_info);
1727 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp