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