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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? short.c

?? 驅(qū)動實(shí)例
?? C
?? 第 1 頁 / 共 2 頁
字號:
	wake_up_interruptible(&short_queue); /* awake any reading process */	return IRQ_HANDLED;}/* * The following two functions are equivalent to the previous one, * but split in top and bottom half. First, a few needed variables */#define NR_TIMEVAL 512 /* length of the array of time values */struct timeval tv_data[NR_TIMEVAL]; /* too lazy to allocate it */volatile struct timeval *tv_head=tv_data;volatile struct timeval *tv_tail=tv_data;static struct work_struct short_wq;int short_wq_count = 0;/* * Increment a circular buffer pointer in a way that nobody sees * an intermediate value. */static inline void short_incr_tv(volatile struct timeval **tvp){	if (*tvp == (tv_data + NR_TIMEVAL - 1))		*tvp = tv_data;	 /* Wrap */	else		(*tvp)++;}void short_do_tasklet (unsigned long unused){	int savecount = short_wq_count, written;	short_wq_count = 0; /* we have already been removed from the queue */	/*	 * The bottom half reads the tv array, filled by the top half,	 * and prints it to the circular text buffer, which is then consumed	 * by reading processes	 */	/* First write the number of interrupts that occurred before this bh */	written = sprintf((char *)short_head,"bh after %6i\n",savecount);	short_incr_bp(&short_head, written);	/*	 * Then, write the time values. Write exactly 16 bytes at a time,	 * so it aligns with PAGE_SIZE	 */	do {		written = sprintf((char *)short_head,"%08u.%06u\n",				(int)(tv_tail->tv_sec % 100000000),				(int)(tv_tail->tv_usec));		short_incr_bp(&short_head, written);		short_incr_tv(&tv_tail);	} while (tv_tail != tv_head);	wake_up_interruptible(&short_queue); /* awake any reading process */}irqreturn_t short_wq_interrupt(int irq, void *dev_id, struct pt_regs *regs){	/* Grab the current time information. */	do_gettimeofday((struct timeval *) tv_head);	short_incr_tv(&tv_head);	/* Queue the bh. Don't worry about multiple enqueueing */	schedule_work(&short_wq);	short_wq_count++; /* record that an interrupt arrived */	return IRQ_HANDLED;}/* * Tasklet top half */irqreturn_t short_tl_interrupt(int irq, void *dev_id, struct pt_regs *regs){	do_gettimeofday((struct timeval *) tv_head); /* cast to stop 'volatile' warning */	short_incr_tv(&tv_head);	tasklet_schedule(&short_tasklet);	short_wq_count++; /* record that an interrupt arrived */	return IRQ_HANDLED;}irqreturn_t short_sh_interrupt(int irq, void *dev_id, struct pt_regs *regs){	int value, written;	struct timeval tv;	/* If it wasn't short, return immediately */	value = inb(short_base);	if (!(value & 0x80))		return IRQ_NONE;		/* clear the interrupting bit */	outb(value & 0x7F, short_base);	/* the rest is unchanged */	do_gettimeofday(&tv);	written = sprintf((char *)short_head,"%08u.%06u\n",			(int)(tv.tv_sec % 100000000), (int)(tv.tv_usec));	short_incr_bp(&short_head, written);	wake_up_interruptible(&short_queue); /* awake any reading process */	return IRQ_HANDLED;}void short_kernelprobe(void){	int count = 0;	do {		unsigned long mask;		mask = probe_irq_on();		outb_p(0x10,short_base+2); /* enable reporting */		outb_p(0x00,short_base);   /* clear the bit */		outb_p(0xFF,short_base);   /* set the bit: interrupt! */		outb_p(0x00,short_base+2); /* disable reporting */		udelay(5);  /* give it some time */		short_irq = probe_irq_off(mask);		if (short_irq == 0) { /* none of them? */			printk(KERN_INFO "short: no irq reported by probe\n");			short_irq = -1;		}		/*		 * if more than one line has been activated, the result is		 * negative. We should service the interrupt (no need for lpt port)		 * and loop over again. Loop at most five times, then give up		 */	} while (short_irq < 0 && count++ < 5);	if (short_irq < 0)		printk("short: probe failed %i times, giving up\n", count);}irqreturn_t short_probing(int irq, void *dev_id, struct pt_regs *regs){	if (short_irq == 0) short_irq = irq;	/* found */	if (short_irq != irq) short_irq = -irq; /* ambiguous */	return IRQ_HANDLED;}void short_selfprobe(void){	int trials[] = {3, 5, 7, 9, 0};	int tried[]  = {0, 0, 0, 0, 0};	int i, count = 0;	/*	 * install the probing handler for all possible lines. Remember	 * the result (0 for success, or -EBUSY) in order to only free	 * what has been acquired      */	for (i = 0; trials[i]; i++)		tried[i] = request_irq(trials[i], short_probing,				SA_INTERRUPT, "short probe", NULL);	do {		short_irq = 0; /* none got, yet */		outb_p(0x10,short_base+2); /* enable */		outb_p(0x00,short_base);		outb_p(0xFF,short_base); /* toggle the bit */		outb_p(0x00,short_base+2); /* disable */		udelay(5);  /* give it some time */		/* the value has been set by the handler */		if (short_irq == 0) { /* none of them? */			printk(KERN_INFO "short: no irq reported by probe\n");		}		/*		 * If more than one line has been activated, the result is		 * negative. We should service the interrupt (but the lpt port		 * doesn't need it) and loop over again. Do it at most 5 times		 */	} while (short_irq <=0 && count++ < 5);	/* end of loop, uninstall the handler */	for (i = 0; trials[i]; i++)		if (tried[i] == 0)			free_irq(trials[i], NULL);	if (short_irq < 0)		printk("short: probe failed %i times, giving up\n", count);}/* Finally, init and cleanup */int short_init(void){	int result;	/*	 * first, sort out the base/short_base ambiguity: we'd better	 * use short_base in the code, for clarity, but allow setting	 * just "base" at load time. Same for "irq".	 */	short_base = base;	short_irq = irq;	/* Get our needed resources. */	if (!use_mem) {		if (! request_region(short_base, SHORT_NR_PORTS, "short")) {			printk(KERN_INFO "short: can't get I/O port address 0x%lx\n",					short_base);			return -ENODEV;		}	} else {		if (! request_mem_region(short_base, SHORT_NR_PORTS, "short")) {			printk(KERN_INFO "short: can't get I/O mem address 0x%lx\n",					short_base);			return -ENODEV;		}		/* also, ioremap it */		short_base = (unsigned long) ioremap(short_base, SHORT_NR_PORTS);		/* Hmm... we should check the return value */	}	/* Here we register our device - should not fail thereafter */	result = register_chrdev(major, "short", &short_fops);	if (result < 0) {		printk(KERN_INFO "short: can't get major number\n");		release_region(short_base,SHORT_NR_PORTS);  /* FIXME - use-mem case? */		return result;	}	if (major == 0) major = result; /* dynamic */	short_buffer = __get_free_pages(GFP_KERNEL,0); /* never fails */  /* FIXME */	short_head = short_tail = short_buffer;	/*	 * Fill the workqueue structure, used for the bottom half handler.	 * The cast is there to prevent warnings about the type of the	 * (unused) argument.	 */	/* this line is in short_init() */	INIT_WORK(&short_wq, (void (*)(void *)) short_do_tasklet, NULL);	/*	 * Now we deal with the interrupt: either kernel-based	 * autodetection, DIY detection or default number	 */	if (short_irq < 0 && probe == 1)		short_kernelprobe();	if (short_irq < 0 && probe == 2)		short_selfprobe();	if (short_irq < 0) /* not yet specified: force the default on */		switch(short_base) {		    case 0x378: short_irq = 7; break;		    case 0x278: short_irq = 2; break;		    case 0x3bc: short_irq = 5; break;		}	/*	 * If shared has been specified, installed the shared handler	 * instead of the normal one. Do it first, before a -EBUSY will	 * force short_irq to -1.	 */	if (short_irq >= 0 && share > 0) {		result = request_irq(short_irq, short_sh_interrupt,				SA_SHIRQ | SA_INTERRUPT,"short",				short_sh_interrupt);		if (result) {			printk(KERN_INFO "short: can't get assigned irq %i\n", short_irq);			short_irq = -1;		}		else { /* actually enable it -- assume this *is* a parallel port */			outb(0x10, short_base+2);		}		return 0; /* the rest of the function only installs handlers */	}	if (short_irq >= 0) {		result = request_irq(short_irq, short_interrupt,				SA_INTERRUPT, "short", NULL);		if (result) {			printk(KERN_INFO "short: can't get assigned irq %i\n",					short_irq);			short_irq = -1;		}		else { /* actually enable it -- assume this *is* a parallel port */			outb(0x10,short_base+2);		}	}	/*	 * Ok, now change the interrupt handler if using top/bottom halves	 * has been requested	 */	if (short_irq >= 0 && (wq + tasklet) > 0) {		free_irq(short_irq,NULL);		result = request_irq(short_irq,				tasklet ? short_tl_interrupt :				short_wq_interrupt,				SA_INTERRUPT,"short-bh", NULL);		if (result) {			printk(KERN_INFO "short-bh: can't get assigned irq %i\n",					short_irq);			short_irq = -1;		}	}	return 0;}void short_cleanup(void){	if (short_irq >= 0) {		outb(0x0, short_base + 2);   /* disable the interrupt */		if (!share) free_irq(short_irq, NULL);		else free_irq(short_irq, short_sh_interrupt);	}	/* Make sure we don't leave work queue/tasklet functions running */	if (tasklet)		tasklet_disable(&short_tasklet);	else		flush_scheduled_work();	unregister_chrdev(major, "short");	if (use_mem) {		iounmap((void __iomem *)short_base);		release_mem_region(short_base, SHORT_NR_PORTS);	} else {		release_region(short_base,SHORT_NR_PORTS);	}	if (short_buffer) free_page(short_buffer);}module_init(short_init);module_exit(short_cleanup);

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
午夜精品久久久久久久久| 一区免费观看视频| 日本特黄久久久高潮| 欧美老肥妇做.爰bbww| 日韩国产欧美在线观看| 91精品国产综合久久福利软件| 亚洲成av人在线观看| 欧美久久久影院| 裸体健美xxxx欧美裸体表演| 欧美精品一区二区三区蜜臀| 国产99久久久久久免费看农村| 欧美韩日一区二区三区| 色www精品视频在线观看| 天天色天天爱天天射综合| 欧美va日韩va| 成人激情小说乱人伦| 亚洲一区二区欧美| 精品国产区一区| av电影在线观看一区| 性做久久久久久| 欧美精品一区二区三区蜜桃| av不卡一区二区三区| 午夜激情一区二区三区| 久久久久久一级片| 91福利视频在线| 国模套图日韩精品一区二区 | 欧美一二三四在线| 国产大片一区二区| 亚洲午夜精品网| 久久午夜电影网| 欧美性受xxxx黑人xyx性爽| 九九视频精品免费| 亚洲色图欧洲色图| 日韩精品一区二区三区视频| 91视视频在线观看入口直接观看www | 91精品久久久久久久99蜜桃| 国产精一区二区三区| 亚洲亚洲精品在线观看| 国产亚洲欧美一区在线观看| 在线精品亚洲一区二区不卡| 国精产品一区一区三区mba视频 | av福利精品导航| 久久国产尿小便嘘嘘| 一区二区三区日韩欧美| 久久久久久**毛片大全| 欧美天堂亚洲电影院在线播放| 国产成人av一区| 久久精品72免费观看| 一区二区三区 在线观看视频| 久久久亚洲国产美女国产盗摄| 欧美亚洲综合色| 波多野结衣在线aⅴ中文字幕不卡| 蜜臀av一区二区在线免费观看| 一区二区三区美女视频| 中文字幕欧美日韩一区| 欧美精品一区二区久久久| 欧美在线不卡视频| 91亚洲精华国产精华精华液| 国产大陆a不卡| 国产一区二区在线电影| 日韩综合小视频| 亚洲国产裸拍裸体视频在线观看乱了 | 91精品午夜视频| 91香蕉视频黄| www.欧美日韩| 成人毛片在线观看| 国产成人鲁色资源国产91色综| 久久激情五月婷婷| 日韩中文字幕区一区有砖一区| 亚洲综合在线第一页| 伊人性伊人情综合网| 亚洲精选在线视频| 亚洲乱码中文字幕| 一区二区三区自拍| 一区二区三区欧美久久| 亚洲欧美aⅴ...| 亚洲欧美日韩久久| 尤物视频一区二区| 亚洲无人区一区| 午夜精品视频在线观看| 日韩 欧美一区二区三区| 婷婷国产在线综合| 亚洲夂夂婷婷色拍ww47| 亚洲欧美日韩系列| 国产亚洲视频系列| 国产清纯白嫩初高生在线观看91| 日韩视频一区在线观看| 日韩一区二区三免费高清| 日韩欧美不卡在线观看视频| 精品国产免费视频| 中文字幕欧美三区| 一区二区三区在线观看国产| 亚洲v日本v欧美v久久精品| 日韩国产精品久久久| 国产一区在线精品| 国产精品一二三四| 不卡的电视剧免费网站有什么| 91麻豆精品视频| 欧美日韩亚洲高清一区二区| 91精品欧美久久久久久动漫| 精品国内二区三区| 国产精品区一区二区三区| 又紧又大又爽精品一区二区| 香蕉成人伊视频在线观看| 激情六月婷婷久久| 日韩欧美自拍偷拍| 久久久午夜电影| 亚洲精品第一国产综合野| 日日夜夜免费精品| 国产最新精品免费| 91国产视频在线观看| 日韩免费视频线观看| 中文字幕av一区二区三区高| 亚洲午夜精品在线| 国产福利不卡视频| 欧美专区亚洲专区| 精品成人免费观看| 一区二区三区视频在线观看| 久久精品国产99| 一本一道久久a久久精品| 日韩免费视频一区| 一区二区三区欧美激情| 国产综合色在线| 在线观看日韩高清av| 国产偷国产偷精品高清尤物| 亚洲不卡在线观看| www.久久精品| 欧美不卡123| 亚洲一区二区三区美女| 成人免费黄色在线| 精品捆绑美女sm三区| 亚洲美女视频在线| 国产精品一区二区男女羞羞无遮挡 | 欧洲一区二区三区在线| 久久日一线二线三线suv| 亚洲一区二区三区激情| 成人污污视频在线观看| 日韩欧美一二三区| 亚洲成人动漫av| 91污在线观看| 欧美国产1区2区| 国内精品伊人久久久久影院对白| 欧美日韩免费电影| 伊人开心综合网| 成人高清伦理免费影院在线观看| 日韩一区二区麻豆国产| 亚洲国产视频在线| 欧美综合一区二区| 亚洲人成小说网站色在线| 懂色av噜噜一区二区三区av| 日韩欧美一区二区视频| 亚洲第一主播视频| 在线观看av一区二区| 亚洲视频每日更新| www.欧美精品一二区| 日本一区二区免费在线观看视频 | 欧美中文字幕不卡| 亚洲欧洲日韩在线| 成人av中文字幕| 欧美国产成人在线| 成人免费视频免费观看| 国产精品蜜臀在线观看| 丁香亚洲综合激情啪啪综合| 久久久精品人体av艺术| 国产美女视频91| 日韩欧美一级片| 精品一区二区三区的国产在线播放| 欧美麻豆精品久久久久久| 首页国产欧美久久| 欧美久久一二区| 蜜臀久久99精品久久久久宅男| 欧美电影在哪看比较好| 男女激情视频一区| 日韩一区二区三区免费观看| 美女视频黄频大全不卡视频在线播放| 4438x亚洲最大成人网| 日本成人中文字幕在线视频| 日韩一级欧美一级| 国产精品456| 中文字幕第一区第二区| 91免费看片在线观看| 亚洲一区二区三区激情| 欧美一区二区大片| 国产精品一线二线三线精华| 国产拍欧美日韩视频二区| 成人精品视频.| 亚洲自拍偷拍欧美| 日韩欧美一级二级三级久久久| 国产在线精品一区二区不卡了| 亚洲国产精品黑人久久久| 色综合一区二区三区| 午夜激情综合网| 久久一二三国产| 91猫先生在线| 免费国产亚洲视频| 国产精品色眯眯| 欧美三级电影在线看| 韩国成人福利片在线播放| 最新国产成人在线观看| 777午夜精品视频在线播放|