xref: /linux/sound/sound_core.c (revision cdd5b5a9761fd66d17586e4f4ba6588c70e640ea)
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
init_oss_soundcore(void)22 static inline int init_oss_soundcore(void)	{ return 0; }
cleanup_oss_soundcore(void)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 
sound_devnode(const struct device * dev,umode_t * mode)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 
init_soundcore(void)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 
cleanup_soundcore(void)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 
__sound_insert_unit(struct sound_unit * s,struct sound_unit ** list,const struct file_operations * fops,int index,int low,int top)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 
__sound_remove_unit(struct sound_unit ** list,int unit)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 
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)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 
sound_remove_unit(struct sound_unit ** list,int unit)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 
register_sound_special_device(const struct file_operations * fops,int unit,struct device * dev)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 
register_sound_special(const struct file_operations * fops,int unit)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 
register_sound_mixer(const struct file_operations * fops,int dev)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 
register_sound_dsp(const struct file_operations * fops,int dev)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 
unregister_sound_special(int unit)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 
unregister_sound_mixer(int unit)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 
unregister_sound_dsp(int unit)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 
__look_for_unit(int chain,int unit)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 
soundcore_open(struct inode * inode,struct file * file)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 
cleanup_oss_soundcore(void)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 
init_oss_soundcore(void)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