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

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

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

~ [ 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