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