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

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

?? short.c

?? 這個是和linux設備驅動第3版配合使用源碼
?? 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一区二区三区免费野_久草精品视频
亚洲狠狠丁香婷婷综合久久久| 欧美videos大乳护士334| 中文字幕一区二区三区不卡在线| 国产在线不卡一区| 久久免费视频一区| 成人一区在线观看| 国产精品不卡在线观看| 色综合久久99| 亚洲午夜三级在线| 777a∨成人精品桃花网| 免费的成人av| xfplay精品久久| 成人综合激情网| 国产精品久久久爽爽爽麻豆色哟哟 | 欧美日韩一区小说| 日韩极品在线观看| 精品国产91九色蝌蚪| 国产九色精品成人porny| 中文字幕一区二区在线播放| 色婷婷综合久久久中文一区二区 | 亚洲国产aⅴ天堂久久| 欧美精品久久一区二区三区| 美女www一区二区| 国产欧美日韩不卡| 在线精品国精品国产尤物884a| 亚洲成av人片| 久久日韩粉嫩一区二区三区| 成人18视频日本| 午夜激情综合网| 久久影院电视剧免费观看| www.色精品| 天天色综合天天| 欧美激情综合在线| 欧美日韩免费一区二区三区 | 国产欧美精品一区aⅴ影院| 色综合久久综合网97色综合| 日韩精品91亚洲二区在线观看| 久久久久久影视| 欧洲亚洲国产日韩| 国产美女在线精品| 一区二区成人在线观看| 国产喂奶挤奶一区二区三区| 欧美亚洲一区二区在线观看| 国产经典欧美精品| 日韩精品三区四区| 亚洲视频狠狠干| 精品国产三级a在线观看| 91成人网在线| 高清不卡一二三区| 欧美a一区二区| 一区二区三区高清不卡| 中文字幕av一区二区三区| 欧美一区二区三区在线观看 | 精品国产一区二区三区久久影院 | 粉嫩一区二区三区在线看| 亚洲国产另类精品专区| 欧美国产日韩精品免费观看| 在线播放中文字幕一区| 色菇凉天天综合网| 国产91在线|亚洲| 韩国毛片一区二区三区| 亚洲高清视频的网址| 中文字幕一区不卡| 久久老女人爱爱| 日韩欧美一区中文| 欧美日韩一卡二卡三卡| 99国产精品久久| 国产电影精品久久禁18| 日韩综合小视频| 亚洲精品一卡二卡| 中文字幕一区二区三区蜜月| 久久久亚洲精品一区二区三区| 欧美一区二区成人| 欧美理论电影在线| 日本电影欧美片| 成人av电影在线| 成人在线视频首页| 国产超碰在线一区| 韩国毛片一区二区三区| 精品在线播放午夜| 久久超碰97中文字幕| 日韩不卡在线观看日韩不卡视频| 亚洲国产精品久久不卡毛片| 亚洲高清免费在线| 亚洲成a人v欧美综合天堂下载| 亚洲女与黑人做爰| 亚洲精品国久久99热| 一区二区高清在线| 亚洲福利视频三区| 日本色综合中文字幕| 另类人妖一区二区av| 美日韩一级片在线观看| 免费成人结看片| 国内成人精品2018免费看| 国产一区二区h| 高清不卡一区二区| av中文字幕亚洲| av电影天堂一区二区在线| 99国产一区二区三精品乱码| 91视频xxxx| 欧美三日本三级三级在线播放| 在线观看中文字幕不卡| 欧洲av在线精品| 欧美日本不卡视频| 欧美一级淫片007| 久久综合九色综合欧美98| 久久亚洲精品国产精品紫薇| 国产亚洲一区二区三区| 亚洲欧洲精品一区二区三区不卡| 中文字幕在线不卡一区二区三区 | 亚洲成人久久影院| 蜜乳av一区二区三区| 国产美女精品在线| 91视频免费观看| 欧美日韩视频在线一区二区| 欧美v日韩v国产v| 国产欧美视频在线观看| 亚洲欧美电影院| 日本系列欧美系列| 国产成a人亚洲精| 在线观看不卡视频| 日韩免费一区二区三区在线播放| 国产女同性恋一区二区| 亚洲激情中文1区| 美女视频黄 久久| 风间由美中文字幕在线看视频国产欧美| 国产a精品视频| 欧美色男人天堂| 久久久久久99久久久精品网站| 国产精品对白交换视频| 亚洲第一激情av| 国产精品资源网站| 欧美自拍偷拍一区| 精品国产免费视频| 亚洲摸摸操操av| 国产精一区二区三区| 在线视频欧美精品| 久久精品亚洲精品国产欧美| 一区二区三区四区不卡视频| 久久狠狠亚洲综合| 欧美精品久久久久久久久老牛影院| 亚洲精品一区二区三区精华液| 亚洲精选视频免费看| 国产一区二区三区四| 在线观看日韩国产| 国产欧美一区二区在线| 蜜臀av性久久久久蜜臀av麻豆| 成人高清在线视频| 精品卡一卡二卡三卡四在线| 亚洲综合一区二区三区| 国产精品综合av一区二区国产馆| 在线观看一区日韩| 中文字幕一区三区| 国产一区二区三区日韩| 7777精品伊人久久久大香线蕉的| 国产精品久久久久久久久久免费看| 日韩精品五月天| 色婷婷香蕉在线一区二区| 欧美成人vps| 午夜精品视频一区| 色狠狠一区二区| 国产欧美精品一区| 狠狠色狠狠色综合| 在线成人小视频| 一区二区三区在线观看网站| 国产馆精品极品| 久久―日本道色综合久久| 麻豆成人综合网| 欧美日韩一区小说| 亚洲欧美激情一区二区| 成人黄色777网| 亚洲国产精品精华液ab| 国产一区二区三区免费看| 日韩精品一区二| 奇米777欧美一区二区| 欧美精品一二三| 亚洲成a天堂v人片| 欧美日韩中文另类| 亚洲一区二区三区四区中文字幕| 99精品欧美一区| 亚洲欧洲国产专区| 91在线视频网址| 亚洲人成精品久久久久| 91蜜桃传媒精品久久久一区二区| 国产精品色婷婷| 不卡的av中国片| 中文字幕字幕中文在线中不卡视频| 成人午夜私人影院| 国产片一区二区| 成人av网址在线观看| ...xxx性欧美| 色播五月激情综合网| 亚洲永久精品大片| 欧美日韩一二区| 婷婷综合久久一区二区三区| 欧美酷刑日本凌虐凌虐| 蜜臀久久99精品久久久久宅男| 欧美一区二区三区四区久久| 日韩高清一级片| 26uuu亚洲|