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

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

?? short.c

?? 《linux設備驅動》3th 源碼 基于2.6的內核
?? 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);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
伊人色综合久久天天| 亚洲欧美一区二区三区国产精品 | 综合久久一区二区三区| 综合在线观看色| 午夜精品久久久| 不卡av免费在线观看| 欧美伊人久久大香线蕉综合69| 欧美一级欧美三级| 亚洲码国产岛国毛片在线| 亚洲国产日产av| 激情小说欧美图片| 欧美电影在线免费观看| 国产精品系列在线| 日韩电影一二三区| 欧美日韩视频在线一区二区| 欧美成人官网二区| 制服丝袜一区二区三区| 亚洲精品免费视频| 国产精品性做久久久久久| 精品一区二区三区av| 在线亚洲高清视频| 欧美国产精品v| 日本伊人精品一区二区三区观看方式| 成人av在线看| 精品欧美黑人一区二区三区| 亚洲黄色av一区| 国产精品一级在线| 久久久91精品国产一区二区精品| 亚洲福利一二三区| proumb性欧美在线观看| 国产精品视频一二| 韩国av一区二区三区在线观看| 欧美性猛交xxxxxx富婆| 欧美va天堂va视频va在线| 亚洲视频一区二区在线| 91在线视频在线| 国产视频一区在线观看| 国产成人午夜99999| 日韩精品一区二区三区视频在线观看 | 久久老女人爱爱| 精品一区二区综合| 91精品久久久久久久久99蜜臂| 亚洲一区二区三区四区的 | 欧美精三区欧美精三区| 国产精品网站在线播放| 国产福利一区二区三区视频| 国产精品美女久久久久av爽李琼| 国产一区二区伦理| 亚洲精品在线一区二区| 成人午夜免费视频| 久久精品人人做人人爽人人| 麻豆一区二区99久久久久| wwwwxxxxx欧美| 国产一区二区三区av电影| 91精品欧美久久久久久动漫 | 成人福利视频在线| 一区二区三区在线视频播放| 91蝌蚪国产九色| 一区二区三区在线观看视频| 欧美精品v日韩精品v韩国精品v| 午夜精品福利一区二区三区av| 99久久99久久精品免费看蜜桃| 亚洲电影在线免费观看| 欧美美女视频在线观看| 麻豆久久久久久久| 亚洲国产激情av| 本田岬高潮一区二区三区| 午夜久久久久久久久| 精品日韩一区二区三区免费视频| 韩国中文字幕2020精品| 亚洲乱码国产乱码精品精的特点| 91成人看片片| 日韩一区欧美二区| 欧美精品一区二区三区很污很色的 | 国产精品系列在线播放| 日韩一区欧美小说| 亚洲精品一区二区三区在线观看| 国产成人午夜电影网| 亚洲视频综合在线| 日韩欧美在线观看一区二区三区| 国产精品亚洲综合一区在线观看| 亚洲影视在线播放| 久久夜色精品国产欧美乱极品| 成人激情图片网| 蜜臀精品一区二区三区在线观看| 欧美国产丝袜视频| 欧美日韩高清在线| 色哟哟欧美精品| 久久精品久久综合| 亚洲成人动漫av| 国产精品视频在线看| 欧美日韩国产a| 91久久精品一区二区| 精品中文字幕一区二区| 国产日韩亚洲欧美综合| 欧美一区日本一区韩国一区| 成人一区在线观看| 激情五月播播久久久精品| 亚洲永久精品大片| 国产日本一区二区| 日韩欧美久久一区| 欧美丝袜丝交足nylons| 美女视频一区在线观看| 一区二区三区影院| 国产拍欧美日韩视频二区| 久久天天做天天爱综合色| 色狠狠综合天天综合综合| 国内精品伊人久久久久av一坑 | 国产精品久久久久天堂| 欧美亚洲精品一区| 欧美亚洲愉拍一区二区| 99国产精品久| 91性感美女视频| 成人一区在线看| 久久 天天综合| 美女网站在线免费欧美精品| 日韩毛片视频在线看| 欧美—级在线免费片| 精品1区2区在线观看| 日韩欧美一二三区| 欧美一区二区三区婷婷月色| 成人99免费视频| 成人一区二区三区中文字幕| 经典三级在线一区| 国产成人午夜精品5599| 国产麻豆一精品一av一免费| 国产成人自拍高清视频在线免费播放| 久久国产福利国产秒拍| 人人狠狠综合久久亚洲| 久久国产日韩欧美精品| 日日摸夜夜添夜夜添国产精品| 亚洲欧洲制服丝袜| 有码一区二区三区| 尤物视频一区二区| 麻豆国产精品777777在线| 日韩av中文字幕一区二区| 亚洲综合成人在线视频| 亚洲国产精品麻豆| 香蕉久久夜色精品国产使用方法| 亚洲夂夂婷婷色拍ww47 | 国产精品久久夜| 国产精品久久久久aaaa| 亚洲毛片av在线| 婷婷综合五月天| 亚洲成av人影院| 国内精品视频一区二区三区八戒| 国产一区二区在线视频| 色综合天天做天天爱| 在线看一区二区| 91福利国产成人精品照片| 日韩视频123| 久久精品在线免费观看| 一区二区三区**美女毛片| 日韩成人av影视| 毛片一区二区三区| 99精品视频一区| 欧美日韩中文精品| 久久精品免费在线观看| 亚洲毛片av在线| 午夜欧美电影在线观看| 国产高清精品久久久久| 色哟哟一区二区三区| 久久久久9999亚洲精品| 国产精品传媒入口麻豆| 亚洲欧美激情一区二区| 青娱乐精品在线视频| 国产精品自拍av| 欧美一级日韩不卡播放免费| 久久精品人人做人人综合| 日韩专区欧美专区| 成人国产精品免费观看动漫| 欧美三级在线看| 亚洲日本中文字幕区| 久久精品国产999大香线蕉| 在线观看视频一区二区| 久久久久久日产精品| 亚洲一区二区三区四区在线免费观看| 韩国精品免费视频| 欧美性色黄大片手机版| 亚洲人成人一区二区在线观看| 日韩av一二三| 欧美片在线播放| 亚洲视频电影在线| 久久精品国产网站| 制服丝袜中文字幕一区| 最新国产精品久久精品| 国产成人免费av在线| 欧美日本不卡视频| 一区二区不卡在线播放| 国产成人aaa| 日韩欧美久久久| 另类的小说在线视频另类成人小视频在线 | 亚洲激情中文1区| 成人免费高清视频| 久久青草欧美一区二区三区| 国产在线播放一区二区三区| 精品视频全国免费看| 一区二区三区高清在线| 成人精品国产福利| 日韩三级伦理片妻子的秘密按摩|