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