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