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