sound_core.c 13 KB

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