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