sound_core.c (14557B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Sound core. This file is composed of two parts. sound_class 4 * which is common to both OSS and ALSA and OSS sound core which 5 * is used OSS or emulation of it. 6 */ 7 8/* 9 * First, the common part. 10 */ 11#include <linux/module.h> 12#include <linux/device.h> 13#include <linux/err.h> 14#include <linux/kdev_t.h> 15#include <linux/major.h> 16#include <sound/core.h> 17 18#ifdef CONFIG_SOUND_OSS_CORE 19static int __init init_oss_soundcore(void); 20static void cleanup_oss_soundcore(void); 21#else 22static inline int init_oss_soundcore(void) { return 0; } 23static inline void cleanup_oss_soundcore(void) { } 24#endif 25 26struct class *sound_class; 27EXPORT_SYMBOL(sound_class); 28 29MODULE_DESCRIPTION("Core sound module"); 30MODULE_AUTHOR("Alan Cox"); 31MODULE_LICENSE("GPL"); 32 33static char *sound_devnode(struct device *dev, umode_t *mode) 34{ 35 if (MAJOR(dev->devt) == SOUND_MAJOR) 36 return NULL; 37 return kasprintf(GFP_KERNEL, "snd/%s", dev_name(dev)); 38} 39 40static int __init init_soundcore(void) 41{ 42 int rc; 43 44 rc = init_oss_soundcore(); 45 if (rc) 46 return rc; 47 48 sound_class = class_create(THIS_MODULE, "sound"); 49 if (IS_ERR(sound_class)) { 50 cleanup_oss_soundcore(); 51 return PTR_ERR(sound_class); 52 } 53 54 sound_class->devnode = sound_devnode; 55 56 return 0; 57} 58 59static void __exit cleanup_soundcore(void) 60{ 61 cleanup_oss_soundcore(); 62 class_destroy(sound_class); 63} 64 65subsys_initcall(init_soundcore); 66module_exit(cleanup_soundcore); 67 68 69#ifdef CONFIG_SOUND_OSS_CORE 70/* 71 * OSS sound core handling. Breaks out sound functions to submodules 72 * 73 * Author: Alan Cox <alan@lxorguk.ukuu.org.uk> 74 * 75 * Fixes: 76 * 77 * -------------------- 78 * 79 * Top level handler for the sound subsystem. Various devices can 80 * plug into this. The fact they don't all go via OSS doesn't mean 81 * they don't have to implement the OSS API. There is a lot of logic 82 * to keeping much of the OSS weight out of the code in a compatibility 83 * module, but it's up to the driver to rember to load it... 84 * 85 * The code provides a set of functions for registration of devices 86 * by type. This is done rather than providing a single call so that 87 * we can hide any future changes in the internals (eg when we go to 88 * 32bit dev_t) from the modules and their interface. 89 * 90 * Secondly we need to allocate the dsp, dsp16 and audio devices as 91 * one. Thus we misuse the chains a bit to simplify this. 92 * 93 * Thirdly to make it more fun and for 2.3.x and above we do all 94 * of this using fine grained locking. 95 * 96 * FIXME: we have to resolve modules and fine grained load/unload 97 * locking at some point in 2.3.x. 98 */ 99 100#include <linux/init.h> 101#include <linux/slab.h> 102#include <linux/types.h> 103#include <linux/kernel.h> 104#include <linux/sound.h> 105#include <linux/kmod.h> 106 107#define SOUND_STEP 16 108 109struct sound_unit 110{ 111 int unit_minor; 112 const struct file_operations *unit_fops; 113 struct sound_unit *next; 114 char name[32]; 115}; 116 117/* 118 * By default, OSS sound_core claims full legacy minor range (0-255) 119 * of SOUND_MAJOR to trap open attempts to any sound minor and 120 * requests modules using custom sound-slot/service-* module aliases. 121 * The only benefit of doing this is allowing use of custom module 122 * aliases instead of the standard char-major-* ones. This behavior 123 * prevents alternative OSS implementation and is scheduled to be 124 * removed. 125 * 126 * CONFIG_SOUND_OSS_CORE_PRECLAIM and soundcore.preclaim_oss kernel 127 * parameter are added to allow distros and developers to try and 128 * switch to alternative implementations without needing to rebuild 129 * the kernel in the meantime. If preclaim_oss is non-zero, the 130 * kernel will behave the same as before. All SOUND_MAJOR minors are 131 * preclaimed and the custom module aliases along with standard chrdev 132 * ones are emitted if a missing device is opened. If preclaim_oss is 133 * zero, sound_core only grabs what's actually in use and for missing 134 * devices only the standard chrdev aliases are requested. 135 * 136 * All these clutters are scheduled to be removed along with 137 * sound-slot/service-* module aliases. 138 */ 139static int preclaim_oss = IS_ENABLED(CONFIG_SOUND_OSS_CORE_PRECLAIM); 140 141module_param(preclaim_oss, int, 0444); 142 143static int soundcore_open(struct inode *, struct file *); 144 145static const struct file_operations soundcore_fops = 146{ 147 /* We must have an owner or the module locking fails */ 148 .owner = THIS_MODULE, 149 .open = soundcore_open, 150 .llseek = noop_llseek, 151}; 152 153/* 154 * Low level list operator. Scan the ordered list, find a hole and 155 * join into it. Called with the lock asserted 156 */ 157 158static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list, const struct file_operations *fops, int index, int low, int top) 159{ 160 int n=low; 161 162 if (index < 0) { /* first free */ 163 164 while (*list && (*list)->unit_minor<n) 165 list=&((*list)->next); 166 167 while(n<top) 168 { 169 /* Found a hole ? */ 170 if(*list==NULL || (*list)->unit_minor>n) 171 break; 172 list=&((*list)->next); 173 n+=SOUND_STEP; 174 } 175 176 if(n>=top) 177 return -ENOENT; 178 } else { 179 n = low+(index*16); 180 while (*list) { 181 if ((*list)->unit_minor==n) 182 return -EBUSY; 183 if ((*list)->unit_minor>n) 184 break; 185 list=&((*list)->next); 186 } 187 } 188 189 /* 190 * Fill it in 191 */ 192 193 s->unit_minor=n; 194 s->unit_fops=fops; 195 196 /* 197 * Link it 198 */ 199 200 s->next=*list; 201 *list=s; 202 203 204 return n; 205} 206 207/* 208 * Remove a node from the chain. Called with the lock asserted 209 */ 210 211static struct sound_unit *__sound_remove_unit(struct sound_unit **list, int unit) 212{ 213 while(*list) 214 { 215 struct sound_unit *p=*list; 216 if(p->unit_minor==unit) 217 { 218 *list=p->next; 219 return p; 220 } 221 list=&(p->next); 222 } 223 printk(KERN_ERR "Sound device %d went missing!\n", unit); 224 return NULL; 225} 226 227/* 228 * This lock guards the sound loader list. 229 */ 230 231static DEFINE_SPINLOCK(sound_loader_lock); 232 233/* 234 * Allocate the controlling structure and add it to the sound driver 235 * list. Acquires locks as needed 236 */ 237 238static int sound_insert_unit(struct sound_unit **list, const struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode, struct device *dev) 239{ 240 struct sound_unit *s = kmalloc(sizeof(*s), GFP_KERNEL); 241 int r; 242 243 if (!s) 244 return -ENOMEM; 245 246 spin_lock(&sound_loader_lock); 247retry: 248 r = __sound_insert_unit(s, list, fops, index, low, top); 249 spin_unlock(&sound_loader_lock); 250 251 if (r < 0) 252 goto fail; 253 else if (r < SOUND_STEP) 254 sprintf(s->name, "sound/%s", name); 255 else 256 sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP); 257 258 if (!preclaim_oss) { 259 /* 260 * Something else might have grabbed the minor. If 261 * first free slot is requested, rescan with @low set 262 * to the next unit; otherwise, -EBUSY. 263 */ 264 r = __register_chrdev(SOUND_MAJOR, s->unit_minor, 1, s->name, 265 &soundcore_fops); 266 if (r < 0) { 267 spin_lock(&sound_loader_lock); 268 __sound_remove_unit(list, s->unit_minor); 269 if (index < 0) { 270 low = s->unit_minor + SOUND_STEP; 271 goto retry; 272 } 273 spin_unlock(&sound_loader_lock); 274 r = -EBUSY; 275 goto fail; 276 } 277 } 278 279 device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor), 280 NULL, "%s", s->name+6); 281 return s->unit_minor; 282 283fail: 284 kfree(s); 285 return r; 286} 287 288/* 289 * Remove a unit. Acquires locks as needed. The drivers MUST have 290 * completed the removal before their file operations become 291 * invalid. 292 */ 293 294static void sound_remove_unit(struct sound_unit **list, int unit) 295{ 296 struct sound_unit *p; 297 298 spin_lock(&sound_loader_lock); 299 p = __sound_remove_unit(list, unit); 300 spin_unlock(&sound_loader_lock); 301 if (p) { 302 if (!preclaim_oss) 303 __unregister_chrdev(SOUND_MAJOR, p->unit_minor, 1, 304 p->name); 305 device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor)); 306 kfree(p); 307 } 308} 309 310/* 311 * Allocations 312 * 313 * 0 *16 Mixers 314 * 1 *8 Sequencers 315 * 2 *16 Midi 316 * 3 *16 DSP 317 * 4 *16 SunDSP 318 * 5 *16 DSP16 319 * 6 -- sndstat (obsolete) 320 * 7 *16 unused 321 * 8 -- alternate sequencer (see above) 322 * 9 *16 raw synthesizer access 323 * 10 *16 unused 324 * 11 *16 unused 325 * 12 *16 unused 326 * 13 *16 unused 327 * 14 *16 unused 328 * 15 *16 unused 329 */ 330 331static struct sound_unit *chains[SOUND_STEP]; 332 333/** 334 * register_sound_special_device - register a special sound node 335 * @fops: File operations for the driver 336 * @unit: Unit number to allocate 337 * @dev: device pointer 338 * 339 * Allocate a special sound device by minor number from the sound 340 * subsystem. 341 * 342 * Return: The allocated number is returned on success. On failure, 343 * a negative error code is returned. 344 */ 345 346int register_sound_special_device(const struct file_operations *fops, int unit, 347 struct device *dev) 348{ 349 const int chain = unit % SOUND_STEP; 350 int max_unit = 256; 351 const char *name; 352 char _name[16]; 353 354 switch (chain) { 355 case 0: 356 name = "mixer"; 357 break; 358 case 1: 359 name = "sequencer"; 360 if (unit >= SOUND_STEP) 361 goto __unknown; 362 max_unit = unit + 1; 363 break; 364 case 2: 365 name = "midi"; 366 break; 367 case 3: 368 name = "dsp"; 369 break; 370 case 4: 371 name = "audio"; 372 break; 373 case 5: 374 name = "dspW"; 375 break; 376 case 8: 377 name = "sequencer2"; 378 if (unit >= SOUND_STEP) 379 goto __unknown; 380 max_unit = unit + 1; 381 break; 382 case 9: 383 name = "dmmidi"; 384 break; 385 case 10: 386 name = "dmfm"; 387 break; 388 case 12: 389 name = "adsp"; 390 break; 391 case 13: 392 name = "amidi"; 393 break; 394 case 14: 395 name = "admmidi"; 396 break; 397 default: 398 { 399 __unknown: 400 sprintf(_name, "unknown%d", chain); 401 if (unit >= SOUND_STEP) 402 strcat(_name, "-"); 403 name = _name; 404 } 405 break; 406 } 407 return sound_insert_unit(&chains[chain], fops, -1, unit, max_unit, 408 name, 0600, dev); 409} 410 411EXPORT_SYMBOL(register_sound_special_device); 412 413int register_sound_special(const struct file_operations *fops, int unit) 414{ 415 return register_sound_special_device(fops, unit, NULL); 416} 417 418EXPORT_SYMBOL(register_sound_special); 419 420/** 421 * register_sound_mixer - register a mixer device 422 * @fops: File operations for the driver 423 * @dev: Unit number to allocate 424 * 425 * Allocate a mixer device. Unit is the number of the mixer requested. 426 * Pass -1 to request the next free mixer unit. 427 * 428 * Return: On success, the allocated number is returned. On failure, 429 * a negative error code is returned. 430 */ 431 432int register_sound_mixer(const struct file_operations *fops, int dev) 433{ 434 return sound_insert_unit(&chains[0], fops, dev, 0, 128, 435 "mixer", 0600, NULL); 436} 437 438EXPORT_SYMBOL(register_sound_mixer); 439 440/* 441 * DSP's are registered as a triple. Register only one and cheat 442 * in open - see below. 443 */ 444 445/** 446 * register_sound_dsp - register a DSP device 447 * @fops: File operations for the driver 448 * @dev: Unit number to allocate 449 * 450 * Allocate a DSP device. Unit is the number of the DSP requested. 451 * Pass -1 to request the next free DSP unit. 452 * 453 * This function allocates both the audio and dsp device entries together 454 * and will always allocate them as a matching pair - eg dsp3/audio3 455 * 456 * Return: On success, the allocated number is returned. On failure, 457 * a negative error code is returned. 458 */ 459 460int register_sound_dsp(const struct file_operations *fops, int dev) 461{ 462 return sound_insert_unit(&chains[3], fops, dev, 3, 131, 463 "dsp", 0600, NULL); 464} 465 466EXPORT_SYMBOL(register_sound_dsp); 467 468/** 469 * unregister_sound_special - unregister a special sound device 470 * @unit: unit number to allocate 471 * 472 * Release a sound device that was allocated with 473 * register_sound_special(). The unit passed is the return value from 474 * the register function. 475 */ 476 477 478void unregister_sound_special(int unit) 479{ 480 sound_remove_unit(&chains[unit % SOUND_STEP], unit); 481} 482 483EXPORT_SYMBOL(unregister_sound_special); 484 485/** 486 * unregister_sound_mixer - unregister a mixer 487 * @unit: unit number to allocate 488 * 489 * Release a sound device that was allocated with register_sound_mixer(). 490 * The unit passed is the return value from the register function. 491 */ 492 493void unregister_sound_mixer(int unit) 494{ 495 sound_remove_unit(&chains[0], unit); 496} 497 498EXPORT_SYMBOL(unregister_sound_mixer); 499 500/** 501 * unregister_sound_dsp - unregister a DSP device 502 * @unit: unit number to allocate 503 * 504 * Release a sound device that was allocated with register_sound_dsp(). 505 * The unit passed is the return value from the register function. 506 * 507 * Both of the allocated units are released together automatically. 508 */ 509 510void unregister_sound_dsp(int unit) 511{ 512 sound_remove_unit(&chains[3], unit); 513} 514 515 516EXPORT_SYMBOL(unregister_sound_dsp); 517 518static struct sound_unit *__look_for_unit(int chain, int unit) 519{ 520 struct sound_unit *s; 521 522 s=chains[chain]; 523 while(s && s->unit_minor <= unit) 524 { 525 if(s->unit_minor==unit) 526 return s; 527 s=s->next; 528 } 529 return NULL; 530} 531 532static int soundcore_open(struct inode *inode, struct file *file) 533{ 534 int chain; 535 int unit = iminor(inode); 536 struct sound_unit *s; 537 const struct file_operations *new_fops = NULL; 538 539 chain=unit&0x0F; 540 if(chain==4 || chain==5) /* dsp/audio/dsp16 */ 541 { 542 unit&=0xF0; 543 unit|=3; 544 chain=3; 545 } 546 547 spin_lock(&sound_loader_lock); 548 s = __look_for_unit(chain, unit); 549 if (s) 550 new_fops = fops_get(s->unit_fops); 551 if (preclaim_oss && !new_fops) { 552 spin_unlock(&sound_loader_lock); 553 554 /* 555 * Please, don't change this order or code. 556 * For ALSA slot means soundcard and OSS emulation code 557 * comes as add-on modules which aren't depend on 558 * ALSA toplevel modules for soundcards, thus we need 559 * load them at first. [Jaroslav Kysela <perex@jcu.cz>] 560 */ 561 request_module("sound-slot-%i", unit>>4); 562 request_module("sound-service-%i-%i", unit>>4, chain); 563 564 /* 565 * sound-slot/service-* module aliases are scheduled 566 * for removal in favor of the standard char-major-* 567 * module aliases. For the time being, generate both 568 * the legacy and standard module aliases to ease 569 * transition. 570 */ 571 if (request_module("char-major-%d-%d", SOUND_MAJOR, unit) > 0) 572 request_module("char-major-%d", SOUND_MAJOR); 573 574 spin_lock(&sound_loader_lock); 575 s = __look_for_unit(chain, unit); 576 if (s) 577 new_fops = fops_get(s->unit_fops); 578 } 579 spin_unlock(&sound_loader_lock); 580 581 if (!new_fops) 582 return -ENODEV; 583 584 /* 585 * We rely upon the fact that we can't be unloaded while the 586 * subdriver is there. 587 */ 588 replace_fops(file, new_fops); 589 590 if (!file->f_op->open) 591 return -ENODEV; 592 593 return file->f_op->open(inode, file); 594} 595 596MODULE_ALIAS_CHARDEV_MAJOR(SOUND_MAJOR); 597 598static void cleanup_oss_soundcore(void) 599{ 600 /* We have nothing to really do here - we know the lists must be 601 empty */ 602 unregister_chrdev(SOUND_MAJOR, "sound"); 603} 604 605static int __init init_oss_soundcore(void) 606{ 607 if (preclaim_oss && 608 register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops) < 0) { 609 printk(KERN_ERR "soundcore: sound device already in use.\n"); 610 return -EBUSY; 611 } 612 613 return 0; 614} 615 616#endif /* CONFIG_SOUND_OSS_CORE */