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

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

?? drivers.c

?? 最新rtlinux內核源碼
?? C
字號:
/*    module/drivers.c    functions for manipulating drivers    COMEDI - Linux Control and Measurement Device Interface    Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>    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.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#define __NO_VERSION__#include <linux/module.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/fcntl.h>#include <linux/delay.h>#include <linux/ioport.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/comedidev.h>#include <linux/wrapper.h>#include <linux/highmem.h>  /* for SuSE brokenness */#include <asm/io.h>static int postconfig(comedi_device *dev);static int insn_rw_emulate_bits(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data);static int insn_inval(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);static void *comedi_recognize(comedi_driver *driv, const char *name);static void comedi_report_boards(comedi_driver *driv);static int poll_invalid(comedi_device *dev,comedi_subdevice *s);int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s,	unsigned long new_size);comedi_driver *comedi_drivers;int comedi_modprobe(kdev_t minor){	return -EINVAL;}int comedi_device_detach(comedi_device *dev){	int i;	comedi_subdevice *s;	if(!dev->attached)		return 0;	/* this is not correct for the kmod case */	if(dev->driver->module)		__MOD_DEC_USE_COUNT(dev->driver->module);	dev->attached=0;	for(i=0;i<dev->n_subdevices;i++){		s=dev->subdevices+i;		if(s->async){			comedi_buf_alloc(dev, s, 0);			if(s->buf_change) s->buf_change(dev,s,0);			kfree(s->async);		}	}	if(dev->driver){		dev->driver->detach(dev);	}else{		printk("BUG: dev->driver=NULL in comedi_device_detach()\n");	}	if(dev->subdevices)kfree(dev->subdevices);	if(dev->private)kfree(dev->private);	return 0;}int comedi_device_attach(comedi_device *dev,comedi_devconfig *it){	comedi_driver *driv;	int ret;	int minor;	int use_count;	if(dev->attached)		return -EBUSY;	minor = dev->minor;	use_count = dev->use_count;	memset(dev,0,sizeof(comedi_device));	spin_lock_init(&dev->spinlock);	dev->minor=minor;	dev->use_count = use_count;	for(driv=comedi_drivers;driv;driv=driv->next){		if(driv->num_names){			dev->board_ptr=comedi_recognize(driv, it->board_name);			if(dev->board_ptr==NULL) continue;		}else{			if(strcmp(driv->driver_name,it->board_name))				continue;		}		//initialize dev->driver here so comedi_error() can be called from attach		dev->driver=driv;		ret=driv->attach(dev,it);		if(ret<0){			driv->detach(dev);			if(dev->subdevices)kfree(dev->subdevices);			if(dev->private)kfree(dev->private);			return ret;		}		goto attached;	}	// recognize has failed if we get here	// report valid board names before returning error	for(driv=comedi_drivers;driv;driv=driv->next){		comedi_report_boards(driv);	}	return -EIO;attached:	/* do a little post-config cleanup */	ret = postconfig(dev);	if(ret < 0)	{		driv->detach(dev);		if(dev->subdevices)kfree(dev->subdevices);		if(dev->private)kfree(dev->private);		return ret;	}	init_waitqueue_head(&dev->read_wait);	init_waitqueue_head(&dev->write_wait);	if(!dev->board_name){		printk("BUG: dev->board_name=<%p>\n",dev->board_name);		dev->board_name="BUG";	}	dev->attached=1;	if(driv->module)		__MOD_INC_USE_COUNT(driv->module);	return 0;}int comedi_driver_register(comedi_driver *driver){	driver->next=comedi_drivers;	comedi_drivers=driver;	return 0;}int comedi_driver_unregister(comedi_driver *driver){	comedi_driver *prev;	int i;	/* check for devices using this driver */	for(i=0;i<COMEDI_NDEVICES;i++){		comedi_device *dev;		dev=comedi_get_device_by_minor(i);		if(dev->attached && dev->driver==driver){			if(dev->use_count)				printk("BUG! detaching device with use_count=%d\n",dev->use_count);			comedi_device_detach(dev);		}	}	if(comedi_drivers==driver){		comedi_drivers=driver->next;		return 0;	}	for(prev=comedi_drivers;prev->next;prev=prev->next){		if(prev->next==driver){			prev->next=driver->next;			return 0;		}	}	return -EINVAL;}comedi_device *comedi_allocate_dev(comedi_driver *driver){	comedi_device *dev;	// XXX we need to do actual allocation here.		dev=comedi_get_device_by_minor(0);	dev->driver=driver;	return dev;}void comedi_deallocate_dev(comedi_device *dev){}static int postconfig(comedi_device *dev){	int i;	comedi_subdevice *s;	comedi_async *async = NULL;	int ret;	for(i=0;i<dev->n_subdevices;i++){		s=dev->subdevices+i;		if(s->type==COMEDI_SUBD_UNUSED)			continue;		if(s->len_chanlist==0)			s->len_chanlist=1; 		if(s->do_cmd){			async = kmalloc(sizeof(comedi_async), GFP_KERNEL);			if(async == NULL)			{				printk("failed to allocate async struct\n");				return -ENOMEM;			}			memset(async, 0, sizeof(comedi_async));			s->async = async;#define DEFAULT_BUF_MAXSIZE (64*1024)#define DEFAULT_BUF_SIZE (64*1024)			async->max_bufsize = DEFAULT_BUF_MAXSIZE;			async->prealloc_buf = NULL;			async->prealloc_bufsz = 0;			if(comedi_buf_alloc(dev,s,DEFAULT_BUF_SIZE) < 0){				printk("Buffer allocation failed\n");				return -ENOMEM;			}			if(s->buf_change){				ret = s->buf_change(dev,s,DEFAULT_BUF_SIZE);				if(ret < 0)return ret;			}		}		if(!s->range_table && !s->range_table_list)			s->range_table=&range_unknown;		if(!s->insn_read && s->insn_bits)			s->insn_read = insn_rw_emulate_bits;		if(!s->insn_write && s->insn_bits)			s->insn_write = insn_rw_emulate_bits;		if(!s->insn_read)s->insn_read = insn_inval;		if(!s->insn_write)s->insn_write = insn_inval;		if(!s->insn_bits)s->insn_bits = insn_inval;		if(!s->insn_config)s->insn_config = insn_inval;		if(!s->poll)s->poll=poll_invalid;	}	return 0;}// generic recognize function for drivers that register their supported board namesvoid *comedi_recognize(comedi_driver *driv, const char *name){	unsigned int i = 0;	void *name_ptr;	name_ptr=driv->board_name;	for(i = 0; i < driv->num_names; i++)	{		if(strcmp(*(char **)name_ptr, name) == 0)			return name_ptr;		name_ptr += driv->offset;	}	return NULL;}void comedi_report_boards(comedi_driver *driv){	unsigned int i;	void *name_ptr;	printk("comedi: valid board names for %s driver are:\n", driv->driver_name);	name_ptr=driv->board_name;	for(i = 0; i < driv->num_names; i++)	{		printk(" %s\n", *(char **)name_ptr);		name_ptr += driv->offset;	}	if(driv->num_names == 0)		printk(" %s\n", driv->driver_name);}static int poll_invalid(comedi_device *dev,comedi_subdevice *s){	return -EINVAL;}static int insn_inval(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){	return -EINVAL;}static int insn_rw_emulate_bits(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data){	comedi_insn new_insn;	int ret;	lsampl_t new_data[2];	unsigned int chan;	chan = CR_CHAN(insn->chanspec);	memset(&new_insn,0,sizeof(new_insn));	new_insn.insn = INSN_BITS;	new_insn.n = 2;	new_insn.data = new_data;	new_insn.subdev = insn->subdev;	if(insn->insn == INSN_WRITE){		if(!(s->subdev_flags & SDF_WRITABLE))			return -EINVAL;		new_data[0] = 1<<chan; /* mask */		new_data[1] = data[0]?(1<<chan):0; /* bits */	}else {		new_data[0] = 0;		new_data[1] = 0;	}	ret = s->insn_bits(dev,s,&new_insn,new_data);	if(ret<0)return ret;	if(insn->insn == INSN_READ){		data[0] = (new_data[1]>>chan)&1;	}	return 1;}static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr){	unsigned long ret = 0UL;	pmd_t *pmd;	pte_t *ptep, pte;	if(!pgd_none(*pgd)){		pmd = pmd_offset(pgd, adr);		if(!pmd_none(*pmd)){			ptep = pte_offset(pmd, adr);			pte = *ptep;			if(pte_present(pte)){				ret = (unsigned long) page_address(pte_page(pte));				ret |= (adr & (PAGE_SIZE - 1));			}		}	}	return ret;}static inline unsigned long kvirt_to_kva(unsigned long adr){	unsigned long va, kva;	va = VMALLOC_VMADDR(adr);	kva = uvirt_to_kva(pgd_offset_k(va), va);	return kva;}int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s,	unsigned long new_size){	comedi_async *async = s->async;	/* if no change is required, do nothing */	if(async->prealloc_buf && async->prealloc_bufsz == new_size){		return 0;	}	if(async->prealloc_bufsz){		int i;		int n_pages = async->prealloc_bufsz >> PAGE_SHIFT;		for(i=0;i<n_pages;i++){			mem_map_unreserve(virt_to_page(__va(__pa(async->buf_page_list[i]))));		}		vfree(async->prealloc_buf);		async->prealloc_buf = NULL;		kfree(async->buf_page_list);		async->buf_page_list = NULL;	}	if(new_size){		unsigned long adr;		int n_pages = new_size >> PAGE_SHIFT;		int i;		async->buf_page_list = kmalloc(sizeof(unsigned long)*n_pages, GFP_KERNEL);		async->prealloc_buf = vmalloc_32(new_size);		if(async->prealloc_buf == NULL){			async->prealloc_bufsz = 0;			kfree(async->buf_page_list);			return -ENOMEM;		}		memset(async->prealloc_buf,0,new_size);		adr = (unsigned long)async->prealloc_buf;		for(i=0;i<n_pages;i++){			async->buf_page_list[i] = kvirt_to_kva(adr);			mem_map_reserve(virt_to_page(__va(__pa(async->buf_page_list[i]))));			adr += PAGE_SIZE;		}	}	async->prealloc_bufsz = new_size;	return 0;}// munging is applied to data right before comedi_buf_write_free()void comedi_buf_munge( comedi_device *dev, comedi_subdevice *s,	unsigned int num_bytes ){	unsigned int offset = s->async->buf_write_ptr;	if( s->munge == NULL || ( s->async->cmd.flags & CMDF_RAWDATA ) )		return;	while( num_bytes )	{		unsigned int block_size;		block_size = num_bytes;		if( (int)(offset + block_size - s->async->prealloc_bufsz) > 0 )			block_size = s->async->prealloc_bufsz - offset;		s->munge( dev, s, s->async->prealloc_buf + offset,			block_size, s->async->munge_chan );		s->async->munge_chan += num_bytes / bytes_per_sample( s );		s->async->munge_chan %= s->async->cmd.chanlist_len;		num_bytes -= block_size;		offset = 0;	}}unsigned int comedi_buf_write_n_available(comedi_async *async){	unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;	return free_end - async->buf_write_alloc_count;}unsigned int comedi_buf_write_alloc(comedi_async *async, unsigned int nbytes){	unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;	if((int)(async->buf_write_alloc_count + nbytes - free_end) > 0){		nbytes = free_end - async->buf_write_alloc_count;	}	async->buf_write_alloc_count += nbytes;	return nbytes;}unsigned int comedi_buf_write_alloc_strict(comedi_async *async,	unsigned int nbytes){	unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;	if((int)(async->buf_write_alloc_count + nbytes - free_end) > 0){		nbytes = 0;	}	async->buf_write_alloc_count += nbytes;	return nbytes;}/* transfers control of a chunk from writer to reader */void comedi_buf_write_free(comedi_async *async, unsigned int nbytes){	async->buf_write_count += nbytes;	async->buf_write_ptr += nbytes;	if(async->buf_write_ptr >= async->prealloc_bufsz){		async->buf_write_ptr %= async->prealloc_bufsz;		async->events |= COMEDI_CB_EOBUF;	}}/* transfers control of a chunk from reader to free area */void comedi_buf_read_free(comedi_async *async, unsigned int nbytes){	async->buf_read_count += nbytes;	async->buf_read_ptr += nbytes;	async->buf_read_ptr %= async->prealloc_bufsz;}void comedi_buf_memcpy_to( comedi_async *async, unsigned int offset, const void *data,	unsigned int num_bytes ){	unsigned int write_ptr = async->buf_write_ptr + offset;	if( write_ptr >= async->prealloc_bufsz )		write_ptr -= async->prealloc_bufsz;	while( num_bytes )	{		unsigned int block_size;		if( write_ptr + num_bytes > async->prealloc_bufsz)			block_size = async->prealloc_bufsz - write_ptr;		else			block_size = num_bytes;		memcpy( async->prealloc_buf + write_ptr, data, block_size );		data += block_size;		num_bytes -= block_size;		write_ptr = 0;	}}void comedi_buf_memcpy_from(comedi_async *async, unsigned int offset,	void *dest, unsigned int nbytes){	void *src;	unsigned int read_ptr = async->buf_read_ptr + offset;	if( read_ptr >= async->prealloc_bufsz )		read_ptr -= async->prealloc_bufsz;	while( nbytes )	{		unsigned int block_size;		src = async->prealloc_buf + read_ptr;		if( nbytes >= async->prealloc_bufsz - read_ptr )			block_size = async->prealloc_bufsz - read_ptr;		else			block_size = nbytes;		memcpy(dest, src, block_size );		nbytes -= block_size;		dest += block_size;		read_ptr = 0;	}}unsigned int comedi_buf_read_n_available(comedi_async *async){	unsigned int read_end = async->buf_write_count;	return read_end - async->buf_read_count;}int comedi_buf_get(comedi_async *async, sampl_t *x){	unsigned int n = comedi_buf_read_n_available(async);	if(n<sizeof(sampl_t))return 0;	*x = *(sampl_t *)(async->prealloc_buf + async->buf_read_ptr);	comedi_buf_read_free(async, sizeof(sampl_t));	return 1;}int comedi_buf_put(comedi_async *async, sampl_t x){	unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(sampl_t));	if(n<sizeof(sampl_t)){		async->events |= COMEDI_CB_ERROR;		return 0;	}	*(sampl_t *)(async->prealloc_buf + async->buf_write_ptr) = x;	comedi_buf_write_free(async, sizeof(sampl_t));	return 1;}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久 天天综合| 久久久99久久| 一区二区成人在线视频| 欧美日韩在线一区二区| 日韩福利电影在线| 夜夜嗨av一区二区三区| 欧美日韩一级黄| 久久精工是国产品牌吗| 久久久久青草大香线综合精品| 国产69精品久久久久777| 亚洲视频精选在线| 538在线一区二区精品国产| 国产又粗又猛又爽又黄91精品| 国产视频一区二区三区在线观看| 成人污视频在线观看| 亚洲一二三区视频在线观看| 欧美成人aa大片| 91国偷自产一区二区开放时间 | 欧美不卡视频一区| 成人免费福利片| 天堂成人免费av电影一区| 国产亚洲欧洲一区高清在线观看| 色999日韩国产欧美一区二区| 久久 天天综合| 亚洲国产精品一区二区久久恐怖片| 欧美变态tickling挠脚心| 在线国产电影不卡| 激情小说欧美图片| 亚洲电影中文字幕在线观看| 日本一区二区免费在线观看视频 | 欧美三级一区二区| 成人av在线一区二区三区| 韩国女主播一区| 久久精品国产免费| 免费在线观看一区| 偷拍一区二区三区| 亚洲福利视频导航| 午夜精品一区二区三区三上悠亚| ...xxx性欧美| 亚洲色图制服诱惑| 亚洲精品视频一区二区| 国内久久婷婷综合| 欧美激情在线一区二区| 精品国产一区二区三区四区四 | 中文字幕精品一区二区精品绿巨人 | wwwwww.欧美系列| 久久婷婷国产综合精品青草| 亚洲综合一二三区| 天堂午夜影视日韩欧美一区二区| 亚洲色图丝袜美腿| 婷婷久久综合九色综合绿巨人| 肉色丝袜一区二区| 亚洲福利一区二区三区| 日韩一区精品字幕| 久久99久久久欧美国产| 老司机精品视频一区二区三区| 国产一区免费电影| 国产精品456露脸| 91偷拍与自偷拍精品| 欧美视频精品在线观看| 日韩精品一区二区三区在线| 日本一区二区三区免费乱视频 | 成人欧美一区二区三区小说| 亚洲国产成人tv| 国产成人免费在线视频| 91论坛在线播放| 91精品国产91久久综合桃花| 久久综合九色综合97婷婷女人 | 日韩中文字幕不卡| 国产伦精一区二区三区| 日本黄色一区二区| 26uuu精品一区二区三区四区在线| 国产精品视频看| 日韩精品国产欧美| 日韩欧美中文字幕公布| 亚洲成人免费在线观看| 99久久99久久精品免费观看| 日韩一级免费一区| 亚洲精品欧美专区| 国产一区二区福利| 日韩欧美自拍偷拍| 青青草国产精品97视觉盛宴| 欧美日韩国产乱码电影| 国产精品国产馆在线真实露脸 | 久久精品久久综合| 精品视频免费看| 亚洲综合一二区| 色噜噜狠狠成人中文综合| 国产精品美女久久久久久久| 国产成都精品91一区二区三 | 欧美中文字幕一区二区三区 | 欧美成人福利视频| 蜜桃久久av一区| 2020国产精品久久精品美国| 蜜桃精品视频在线| 久久久久久久一区| 高清不卡一区二区在线| 国产精品久久久久一区| 99在线热播精品免费| 亚洲精品欧美激情| 欧美日韩国产精选| 成人免费一区二区三区在线观看| 久久久久国产精品人| 蜜桃av噜噜一区二区三区小说| 91精品在线麻豆| 国产自产高清不卡| 17c精品麻豆一区二区免费| 男人的j进女人的j一区| 欧美喷潮久久久xxxxx| 精品一区二区三区免费播放| 一区在线观看视频| 欧美精品aⅴ在线视频| 久久se精品一区二区| 中文字幕亚洲电影| 精品国产青草久久久久福利| 99久久精品免费精品国产| 日韩国产在线一| 国产精品理伦片| 欧美精选在线播放| 福利一区二区在线观看| 亚洲国产精品嫩草影院| 日本一区二区成人在线| 正在播放亚洲一区| 91玉足脚交白嫩脚丫在线播放| 麻豆高清免费国产一区| 亚洲一区在线观看网站| 国产精品成人一区二区艾草 | 久久精品视频在线看| 5月丁香婷婷综合| 91福利国产成人精品照片| 国产精品亚洲专一区二区三区 | 日韩国产欧美在线播放| 亚洲一区二区三区视频在线| 中文字幕色av一区二区三区| 久久久不卡网国产精品二区| 精品美女在线播放| 日韩精品一区二区三区四区| 5858s免费视频成人| 日韩三级.com| 亚洲精品一线二线三线| 久久综合久久综合久久| 久久综合色天天久久综合图片| 精品人在线二区三区| 久久综合狠狠综合久久激情| 欧美精品一区二区三区高清aⅴ| 精品国精品国产| 国产精品午夜电影| 亚洲视频一二三| 午夜精品久久久久久久99樱桃| 午夜精品爽啪视频| 久久国产欧美日韩精品| 国产999精品久久| 欧美最猛性xxxxx直播| 91精品国产一区二区人妖| 精品国产乱码久久久久久图片 | 蜜臀av一级做a爰片久久| 国内偷窥港台综合视频在线播放| 韩国一区二区三区| 99久久精品国产观看| 91.com在线观看| 国产欧美一二三区| 亚洲国产精品一区二区久久| 极品销魂美女一区二区三区| 成人高清视频免费观看| 91麻豆精品国产91| 国产精品大尺度| 国产一区二区伦理| 欧美精品777| 国产精品欧美极品| 久久99热这里只有精品| 色婷婷久久久亚洲一区二区三区| 欧美一级高清大全免费观看| 国产精品伦理在线| 国产一区二区三区在线看麻豆| 欧美日韩中文字幕一区| 亚洲色图制服丝袜| 懂色一区二区三区免费观看| 欧美一区二区不卡视频| 亚洲大片在线观看| 一本大道av伊人久久综合| 国产精品久久久久影院| 国产成人亚洲综合色影视| 日韩一区二区电影网| 亚洲成av人片在线观看| 日本久久精品电影| 亚洲综合无码一区二区| 一本久久a久久精品亚洲| 国产精品久久久久久久久快鸭| 成人天堂资源www在线| 久久精品亚洲乱码伦伦中文| 国产一区二区免费视频| 欧美国产一区视频在线观看| 成人av网站免费观看| 亚洲激情在线激情| 91精品国产欧美日韩| 久久精品国产99久久6| 久久久亚洲高清| 91亚洲国产成人精品一区二区三| 亚洲欧美日韩国产综合| 欧美日韩一区在线观看|