亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? sound_core.c

?? 這個源碼相信對很多用arm開發板開發的人會有用的
?? C
字號:
/* *	Sound core handling. Breaks out sound functions to submodules *	 *	Author:		Alan Cox <alan.cox@linux.org> * *	Fixes: * * *	This program is free software; you can redistribute it and/or *	modify it under the terms of the GNU General Public License *	as published by the Free Software Foundation; either version *	2 of the License, or (at your option) any later version. * *                         -------------------- *  *	Top level handler for the sound subsystem. Various devices can *	plug into this. The fact they don't all go via OSS doesn't mean  *	they don't have to implement the OSS API. There is a lot of logic *	to keeping much of the OSS weight out of the code in a compatibility *	module, but it's up to the driver to rember to load it... * *	The code provides a set of functions for registration of devices *	by type. This is done rather than providing a single call so that *	we can hide any future changes in the internals (eg when we go to *	32bit dev_t) from the modules and their interface. * *	Secondly we need to allocate the dsp, dsp16 and audio devices as *	one. Thus we misuse the chains a bit to simplify this. * *	Thirdly to make it more fun and for 2.3.x and above we do all *	of this using fine grained locking. * *	FIXME: we have to resolve modules and fine grained load/unload *	locking at some point in 2.3.x. */#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/sound.h>#include <linux/major.h>#include <linux/kmod.h>#include <linux/devfs_fs_kernel.h>#include <linux/device.h>#define SOUND_STEP 16struct sound_unit{	int unit_minor;	struct file_operations *unit_fops;	struct sound_unit *next;	char name[32];};#ifdef CONFIG_SOUND_MSNDCLASextern int msnd_classic_init(void);#endif#ifdef CONFIG_SOUND_MSNDPINextern int msnd_pinnacle_init(void);#endifstruct class *sound_class;EXPORT_SYMBOL(sound_class);/* *	Low level list operator. Scan the ordered list, find a hole and *	join into it. Called with the lock asserted */static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list, struct file_operations *fops, int index, int low, int top){	int n=low;	if (index < 0) {	/* first free */		while (*list && (*list)->unit_minor<n)			list=&((*list)->next);		while(n<top)		{			/* Found a hole ? */			if(*list==NULL || (*list)->unit_minor>n)				break;			list=&((*list)->next);			n+=SOUND_STEP;		}		if(n>=top)			return -ENOENT;	} else {		n = low+(index*16);		while (*list) {			if ((*list)->unit_minor==n)				return -EBUSY;			if ((*list)->unit_minor>n)				break;			list=&((*list)->next);		}	}				/*	 *	Fill it in	 */	 	s->unit_minor=n;	s->unit_fops=fops;		/*	 *	Link it	 */	 	s->next=*list;	*list=s;			return n;}/* *	Remove a node from the chain. Called with the lock asserted */ static struct sound_unit *__sound_remove_unit(struct sound_unit **list, int unit){	while(*list)	{		struct sound_unit *p=*list;		if(p->unit_minor==unit)		{			*list=p->next;			return p;		}		list=&(p->next);	}	printk(KERN_ERR "Sound device %d went missing!\n", unit);	return NULL;}/* *	This lock guards the sound loader list. */static DEFINE_SPINLOCK(sound_loader_lock);/* *	Allocate the controlling structure and add it to the sound driver *	list. Acquires locks as needed */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, struct device *dev){	struct sound_unit *s = kmalloc(sizeof(*s), GFP_KERNEL);	int r;	if (!s)		return -ENOMEM;			spin_lock(&sound_loader_lock);	r = __sound_insert_unit(s, list, fops, index, low, top);	spin_unlock(&sound_loader_lock);		if (r < 0)		goto fail;	else if (r < SOUND_STEP)		sprintf(s->name, "sound/%s", name);	else		sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);	devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor),			S_IFCHR | mode, s->name);	class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, s->unit_minor),			    dev, s->name+6);	return r; fail:	kfree(s);	return r;}/* *	Remove a unit. Acquires locks as needed. The drivers MUST have *	completed the removal before their file operations become *	invalid. */ 	static void sound_remove_unit(struct sound_unit **list, int unit){	struct sound_unit *p;	spin_lock(&sound_loader_lock);	p = __sound_remove_unit(list, unit);	spin_unlock(&sound_loader_lock);	if (p) {		devfs_remove(p->name);		class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor));		kfree(p);	}}/* *	Allocations * *	0	*16		Mixers *	1	*8		Sequencers *	2	*16		Midi *	3	*16		DSP *	4	*16		SunDSP *	5	*16		DSP16 *	6	--		sndstat (obsolete) *	7	*16		unused *	8	--		alternate sequencer (see above) *	9	*16		raw synthesizer access *	10	*16		unused *	11	*16		unused *	12	*16		unused *	13	*16		unused *	14	*16		unused *	15	*16		unused */static struct sound_unit *chains[SOUND_STEP];/** *	register_sound_special_device - register a special sound node *	@fops: File operations for the driver *	@unit: Unit number to allocate *      @dev: device pointer * *	Allocate a special sound device by minor number from the sound *	subsystem. The allocated number is returned on succes. On failure *	a negative error code is returned. */ int register_sound_special_device(struct file_operations *fops, int unit,				  struct device *dev){	const int chain = unit % SOUND_STEP;	int max_unit = 128 + chain;	const char *name;	char _name[16];	switch (chain) {	    case 0:		name = "mixer";		break;	    case 1:		name = "sequencer";		if (unit >= SOUND_STEP)			goto __unknown;		max_unit = unit + 1;		break;	    case 2:		name = "midi";		break;	    case 3:		name = "dsp";		break;	    case 4:		name = "audio";		break;	    case 8:		name = "sequencer2";		if (unit >= SOUND_STEP)			goto __unknown;		max_unit = unit + 1;		break;	    case 9:		name = "dmmidi";		break;	    case 10:		name = "dmfm";		break;	    case 12:		name = "adsp";		break;	    case 13:		name = "amidi";		break;	    case 14:		name = "admmidi";		break;	    default:	    	{		    __unknown:			sprintf(_name, "unknown%d", chain);		    	if (unit >= SOUND_STEP)		    		strcat(_name, "-");		    	name = _name;		}		break;	}	return sound_insert_unit(&chains[chain], fops, -1, unit, max_unit,				 name, S_IRUSR | S_IWUSR, dev);} EXPORT_SYMBOL(register_sound_special_device);int register_sound_special(struct file_operations *fops, int unit){	return register_sound_special_device(fops, unit, NULL);}EXPORT_SYMBOL(register_sound_special);/** *	register_sound_mixer - register a mixer device *	@fops: File operations for the driver *	@dev: Unit number to allocate * *	Allocate a mixer device. Unit is the number of the mixer requested. *	Pass -1 to request the next free mixer unit. On success the allocated *	number is returned, on failure a negative error code is returned. */int register_sound_mixer(struct file_operations *fops, int dev){	return sound_insert_unit(&chains[0], fops, dev, 0, 128,				 "mixer", S_IRUSR | S_IWUSR, NULL);}EXPORT_SYMBOL(register_sound_mixer);/** *	register_sound_midi - register a midi device *	@fops: File operations for the driver *	@dev: Unit number to allocate * *	Allocate a midi device. Unit is the number of the midi device requested. *	Pass -1 to request the next free midi unit. On success the allocated *	number is returned, on failure a negative error code is returned. */int register_sound_midi(struct file_operations *fops, int dev){	return sound_insert_unit(&chains[2], fops, dev, 2, 130,				 "midi", S_IRUSR | S_IWUSR, NULL);}EXPORT_SYMBOL(register_sound_midi);/* *	DSP's are registered as a triple. Register only one and cheat *	in open - see below. */ /** *	register_sound_dsp - register a DSP device *	@fops: File operations for the driver *	@dev: Unit number to allocate * *	Allocate a DSP device. Unit is the number of the DSP requested. *	Pass -1 to request the next free DSP unit. On success the allocated *	number is returned, on failure a negative error code is returned. * *	This function allocates both the audio and dsp device entries together *	and will always allocate them as a matching pair - eg dsp3/audio3 */int register_sound_dsp(struct file_operations *fops, int dev){	return sound_insert_unit(&chains[3], fops, dev, 3, 131,				 "dsp", S_IWUSR | S_IRUSR, NULL);}EXPORT_SYMBOL(register_sound_dsp);/** *	register_sound_synth - register a synth device *	@fops: File operations for the driver *	@dev: Unit number to allocate * *	Allocate a synth device. Unit is the number of the synth device requested. *	Pass -1 to request the next free synth unit. On success the allocated *	number is returned, on failure a negative error code is returned. */int register_sound_synth(struct file_operations *fops, int dev){	return sound_insert_unit(&chains[9], fops, dev, 9, 137,				 "synth", S_IRUSR | S_IWUSR, NULL);}EXPORT_SYMBOL(register_sound_synth);/** *	unregister_sound_special - unregister a special sound device *	@unit: unit number to allocate * *	Release a sound device that was allocated with *	register_sound_special(). The unit passed is the return value from *	the register function. */void unregister_sound_special(int unit){	sound_remove_unit(&chains[unit % SOUND_STEP], unit);} EXPORT_SYMBOL(unregister_sound_special);/** *	unregister_sound_mixer - unregister a mixer *	@unit: unit number to allocate * *	Release a sound device that was allocated with register_sound_mixer(). *	The unit passed is the return value from the register function. */void unregister_sound_mixer(int unit){	sound_remove_unit(&chains[0], unit);}EXPORT_SYMBOL(unregister_sound_mixer);/** *	unregister_sound_midi - unregister a midi device *	@unit: unit number to allocate * *	Release a sound device that was allocated with register_sound_midi(). *	The unit passed is the return value from the register function. */void unregister_sound_midi(int unit){	return sound_remove_unit(&chains[2], unit);}EXPORT_SYMBOL(unregister_sound_midi);/** *	unregister_sound_dsp - unregister a DSP device *	@unit: unit number to allocate * *	Release a sound device that was allocated with register_sound_dsp(). *	The unit passed is the return value from the register function. * *	Both of the allocated units are released together automatically. */void unregister_sound_dsp(int unit){	return sound_remove_unit(&chains[3], unit);}EXPORT_SYMBOL(unregister_sound_dsp);/** *	unregister_sound_synth - unregister a synth device *	@unit: unit number to allocate * *	Release a sound device that was allocated with register_sound_synth(). *	The unit passed is the return value from the register function. */void unregister_sound_synth(int unit){	return sound_remove_unit(&chains[9], unit);}EXPORT_SYMBOL(unregister_sound_synth);/* *	Now our file operations */static int soundcore_open(struct inode *, struct file *);static struct file_operations soundcore_fops={	/* We must have an owner or the module locking fails */	.owner	= THIS_MODULE,	.open	= soundcore_open,};static struct sound_unit *__look_for_unit(int chain, int unit){	struct sound_unit *s;		s=chains[chain];	while(s && s->unit_minor <= unit)	{		if(s->unit_minor==unit)			return s;		s=s->next;	}	return NULL;}int soundcore_open(struct inode *inode, struct file *file){	int chain;	int unit = iminor(inode);	struct sound_unit *s;	struct file_operations *new_fops = NULL;	chain=unit&0x0F;	if(chain==4 || chain==5)	/* dsp/audio/dsp16 */	{		unit&=0xF0;		unit|=3;		chain=3;	}		spin_lock(&sound_loader_lock);	s = __look_for_unit(chain, unit);	if (s)		new_fops = fops_get(s->unit_fops);	if (!new_fops) {		spin_unlock(&sound_loader_lock);		/*		 *  Please, don't change this order or code.		 *  For ALSA slot means soundcard and OSS emulation code		 *  comes as add-on modules which aren't depend on		 *  ALSA toplevel modules for soundcards, thus we need		 *  load them at first.	  [Jaroslav Kysela <perex@jcu.cz>]		 */		request_module("sound-slot-%i", unit>>4);		request_module("sound-service-%i-%i", unit>>4, chain);		spin_lock(&sound_loader_lock);		s = __look_for_unit(chain, unit);		if (s)			new_fops = fops_get(s->unit_fops);	}	if (new_fops) {		/*		 * We rely upon the fact that we can't be unloaded while the		 * subdriver is there, so if ->open() is successful we can		 * safely drop the reference counter and if it is not we can		 * revert to old ->f_op. Ugly, indeed, but that's the cost of		 * switching ->f_op in the first place.		 */		int err = 0;		struct file_operations *old_fops = file->f_op;		file->f_op = new_fops;		spin_unlock(&sound_loader_lock);		if(file->f_op->open)			err = file->f_op->open(inode,file);		if (err) {			fops_put(file->f_op);			file->f_op = fops_get(old_fops);		}		fops_put(old_fops);		return err;	}	spin_unlock(&sound_loader_lock);	return -ENODEV;}extern int mod_firmware_load(const char *, char **);EXPORT_SYMBOL(mod_firmware_load);MODULE_DESCRIPTION("Core sound module");MODULE_AUTHOR("Alan Cox");MODULE_LICENSE("GPL");MODULE_ALIAS_CHARDEV_MAJOR(SOUND_MAJOR);static void __exit cleanup_soundcore(void){	/* We have nothing to really do here - we know the lists must be	   empty */	unregister_chrdev(SOUND_MAJOR, "sound");	devfs_remove("sound");	class_destroy(sound_class);}static int __init init_soundcore(void){	if (register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops)==-1) {		printk(KERN_ERR "soundcore: sound device already in use.\n");		return -EBUSY;	}	devfs_mk_dir ("sound");	sound_class = class_create(THIS_MODULE, "sound");	if (IS_ERR(sound_class))		return PTR_ERR(sound_class);	return 0;}module_init(init_soundcore);module_exit(cleanup_soundcore);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
99re成人精品视频| 国产精品自拍在线| 国产福利一区二区| 欧美男人的天堂一二区| 日本一区二区三区高清不卡| 亚洲日本va午夜在线电影| 国产成人在线视频免费播放| 欧美另类z0zxhd电影| 中文字幕一区二区三区四区| 奇米色一区二区| 91精品福利视频| 国产精品国产三级国产aⅴ中文| 日本va欧美va瓶| 91精品国产乱码| 亚洲成人av福利| 色噜噜狠狠一区二区三区果冻| 欧美经典一区二区| 国内久久精品视频| 日韩欧美国产午夜精品| 青青草97国产精品免费观看| 欧美疯狂做受xxxx富婆| 亚洲一区av在线| 在线观看日韩av先锋影音电影院| 国产精品久久毛片av大全日韩| 国产精品亚洲а∨天堂免在线| 精品毛片乱码1区2区3区| 久久精品国产一区二区| 日韩一级免费观看| 免费人成网站在线观看欧美高清| 91精品免费在线观看| 日日骚欧美日韩| 制服丝袜亚洲精品中文字幕| 午夜av区久久| 欧美一区二区三区啪啪| 日韩精品乱码免费| 日韩欧美亚洲一区二区| 欧美aaaaa成人免费观看视频| 欧美一区二区啪啪| 免费一级片91| 国产午夜精品一区二区三区视频| 国产成人免费高清| 蜜臀av性久久久久蜜臀aⅴ流畅 | 国产一区二区三区四| 久久综合久久综合久久| 国产成人综合亚洲网站| 中文字幕一区二区三区色视频 | 成人黄色小视频| 国产精品高潮呻吟| 色噜噜狠狠成人中文综合| 亚洲国产精品人人做人人爽| 欧美日韩高清影院| 国产伦精一区二区三区| 亚洲欧美一区二区不卡| 91精品国产综合久久蜜臀| 国产在线视视频有精品| 国产精品久线观看视频| 日本高清不卡视频| 日本91福利区| 国产精品美女久久久久久2018| 色综合久久精品| 美女视频第一区二区三区免费观看网站| 欧美一区二区网站| 不卡一区二区中文字幕| 午夜av一区二区| 国产精品毛片久久久久久| 91传媒视频在线播放| 久久99精品一区二区三区| 欧美激情一区二区在线| 欧美精品亚洲一区二区在线播放| 精品亚洲国产成人av制服丝袜| 日韩毛片高清在线播放| 日韩欧美精品在线视频| 99国产欧美另类久久久精品| 日韩av电影天堂| 亚洲天堂精品视频| 日韩美女视频一区二区在线观看| 97久久久精品综合88久久| 国精产品一区一区三区mba视频| 亚洲乱码中文字幕综合| 久久蜜桃av一区精品变态类天堂| 日本高清不卡视频| 成人免费毛片片v| 精品在线一区二区| 视频一区视频二区在线观看| 中文字幕一区日韩精品欧美| 精品国产乱码久久久久久影片| 日本韩国一区二区三区视频| 国产麻豆日韩欧美久久| 日韩和欧美一区二区三区| 亚洲三级电影全部在线观看高清| 精品美女被调教视频大全网站| 欧美顶级少妇做爰| 欧美亚洲高清一区| 91丨porny丨最新| 成人妖精视频yjsp地址| 韩国av一区二区三区| 日精品一区二区三区| 亚洲综合偷拍欧美一区色| 国产精品久久久久久亚洲伦| 久久精品夜色噜噜亚洲a∨| 日韩精品一区二区三区swag| 91精品国产综合久久精品| 欧美亚日韩国产aⅴ精品中极品| av网站免费线看精品| 丰满少妇久久久久久久| 国产麻豆一精品一av一免费| 国产一区二区中文字幕| 久久er99精品| 久久成人免费网| 久久国产精品72免费观看| 蜜臀国产一区二区三区在线播放| 午夜视频一区在线观看| 香蕉久久夜色精品国产使用方法| 一区二区三区日韩| 亚洲综合自拍偷拍| 亚洲无线码一区二区三区| 亚洲午夜免费电影| 日韩精品一二三| 久久黄色级2电影| 国产一区二区网址| 国产.精品.日韩.另类.中文.在线.播放 | 久久疯狂做爰流白浆xx| 激情久久五月天| 国产乱码精品一区二区三区五月婷 | 99r国产精品| 91福利国产精品| 91精品国产综合久久久久久| 日韩免费一区二区三区在线播放| 精品日韩一区二区三区免费视频| 久久日韩粉嫩一区二区三区| 国产欧美日本一区二区三区| 日韩一区中文字幕| 亚洲成人自拍一区| 国产一区二区三区免费看 | 自拍偷拍欧美精品| 亚洲成av人片在www色猫咪| 美女网站一区二区| 国产福利电影一区二区三区| 91色综合久久久久婷婷| 欧美人妇做爰xxxⅹ性高电影| 欧美一级免费大片| 国产欧美日韩精品a在线观看| 亚洲精品国产品国语在线app| 日韩av一二三| 白白色 亚洲乱淫| 6080亚洲精品一区二区| 国产视频在线观看一区二区三区 | 91丨九色丨黑人外教| 7777精品久久久大香线蕉| 久久久久久久国产精品影院| 一二三四区精品视频| 激情综合网最新| 91久久一区二区| 久久免费午夜影院| 亚洲aⅴ怡春院| 白白色亚洲国产精品| 91精品啪在线观看国产60岁| 国产精品素人视频| 亚洲国产成人精品视频| 国产成人免费av在线| 欧美一区二区三区人| 一区二区三区在线观看网站| 精品一区二区av| 欧美日韩视频第一区| 中文字幕高清一区| 免费看精品久久片| 色香色香欲天天天影视综合网| 欧美成人video| 亚洲chinese男男1069| av一区二区三区黑人| 久久久99免费| 蜜臀av一区二区| 欧美精品 国产精品| 亚洲品质自拍视频网站| 国产乱码字幕精品高清av| 91精品蜜臀在线一区尤物| 亚洲综合色区另类av| av爱爱亚洲一区| 国产日韩欧美不卡| 国产一区 二区| 久久一日本道色综合| 老汉av免费一区二区三区| 欧美日韩成人高清| 亚洲高清免费视频| 欧美色手机在线观看| 亚洲精品视频在线看| 99麻豆久久久国产精品免费| 欧美激情一区二区三区全黄| 国产伦理精品不卡| 久久久久久久久久久久久久久99| 久久成人羞羞网站| 久久综合九色综合97婷婷| 男女激情视频一区| 欧美成人女星排行榜| 久久er精品视频| 久久久无码精品亚洲日韩按摩| 狠狠色狠狠色综合| 国产午夜精品久久久久久免费视 | 欧美丰满少妇xxxbbb| 亚洲成av人片|