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