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

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

?? serial.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁(yè) / 共 4 頁(yè)
字號(hào):
			if (recheck_count > 16)
				printk("recheck_count = %d\n", recheck_count);
#endif
		}
#ifdef ISR_HACK
		serial_outp(info, UART_IER, 0);
		serial_out(info, UART_IER, info->IER);
#endif
		
		info = info->next_port;
		if (!info && !done) {
			info = IRQ_ports[irq];
			done = 1;
			if (pass_number++ > 64)
				break; 		/* Prevent infinite loops */
		}
	}
	if ((info = IRQ_ports[irq]) != NULL) {
#ifdef 0
		do {
			serial_outp(info, UART_IER, 0);
			serial_out(info, UART_IER, info->IER);
			info = info->next_port;
		} while (info);
#endif			
		if (irq && !done_work)
			IRQ_timer[irq] = jiffies + 1500;
		else
			IRQ_timer[irq] = jiffies + IRQ_timeout[irq];
		IRQ_active |= 1 << irq;
	}
	figure_RS_timer();
}

/*
 * -------------------------------------------------------------------
 * Here ends the serial interrupt routines.
 * -------------------------------------------------------------------
 */

/*
 * This routine is called when we receive a break on a serial line.
 * It is executed out of the software interrupt routine.
 */
static inline void handle_rs_break(struct async_struct *info)
{
	if (info->flags & ASYNC_SAK)
		do_SAK(info->tty);
		
	if (!I_IGNBRK(info->tty) && I_BRKINT(info->tty)) {
		flush_input(info->tty);
		flush_output(info->tty);
		if (info->tty->pgrp > 0)
			kill_pg(info->tty->pgrp, SIGINT,1);
	}
}

/*
 * This routine is used to handle the "bottom half" processing for the
 * serial driver, known also the "software interrupt" processing.
 * This processing is done at the kernel interrupt level, after the
 * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
 * is where time-consuming activities which can not be done in the
 * interrupt driver proper are done; the interrupt driver schedules
 * them using rs_sched_event(), and they get done here.
 */
static void do_softint(void *unused)
{
	int			i;
	struct async_struct	*info;
	
	for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
		if (clear_bit(i, rs_event)) {
			if (!info->tty)	
				continue;
			if (clear_bit(RS_EVENT_READ_PROCESS, &info->event)) {
				TTY_READ_FLUSH(info->tty);
			}
			if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
				wake_up_interruptible(&info->tty->write_q.proc_list);
			}
			if (clear_bit(RS_EVENT_HANGUP, &info->event)) {
				tty_hangup(info->tty);
				wake_up_interruptible(&info->open_wait);
				info->flags &= ~(ASYNC_NORMAL_ACTIVE|
						 ASYNC_CALLOUT_ACTIVE);
			}
			if (clear_bit(RS_EVENT_BREAK, &info->event))
				handle_rs_break(info);
			if (clear_bit(RS_EVENT_OPEN_WAKEUP, &info->event)) {
				wake_up_interruptible(&info->open_wait);
			}
		}
	}
}

/*
 * This subroutine is called when the RS_TIMER goes off.  It is used
 * by the serial driver to run the rs_interrupt routine at certain
 * intervals, either because a serial interrupt might have been lost,
 * or because (in the case of IRQ=0) the serial port does not have an
 * interrupt, and is being checked only via the timer interrupts.
 */
static void rs_timer(void)
{
	int	i, mask;
	int	timeout = 0;

	for (i = 0, mask = 1; mask <= IRQ_active; i++, mask <<= 1) {
		if ((mask & IRQ_active) && (IRQ_timer[i] <= jiffies)) {
			IRQ_active &= ~mask;
			cli();
#ifdef SERIAL_DEBUG_TIMER
			printk("rs_timer: rs_interrupt(%d)...", i);
#endif
			rs_interrupt(i);
			sti();
		}
		if (mask & IRQ_active) {
			if (!timeout || (IRQ_timer[i] < timeout))
				timeout = IRQ_timer[i];
		}
	}
	if (timeout) {
		timer_table[RS_TIMER].expires = timeout;
		timer_active |= 1 << RS_TIMER;
	}
}

/*
 * ---------------------------------------------------------------
 * Low level utility subroutines for the serial driver:  routines to
 * figure out the appropriate timeout for an interrupt chain, routines
 * to initialize and startup a serial port, and routines to shutdown a
 * serial port.  Useful stuff like that.
 * ---------------------------------------------------------------
 */

/*
 * Grab all interrupts in preparation for doing an automatic irq
 * detection.  dontgrab is a mask of irq's _not_ to grab.  Returns a
 * mask of irq's which were grabbed and should therefore be freed
 * using free_all_interrupts().
 */
static int grab_all_interrupts(int dontgrab)
{
	int 			irq_lines = 0;
	int			i, mask;
	struct sigaction 	sa;
	
	sa.sa_handler = rs_probe;
	sa.sa_flags = (SA_INTERRUPT);
	sa.sa_mask = 0;
	sa.sa_restorer = NULL;
	
	for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
		if (!(mask & dontgrab) && !irqaction(i, &sa)) {
			irq_lines |= mask;
		}
	}
	return irq_lines;
}

/*
 * Release all interrupts grabbed by grab_all_interrupts
 */
static void free_all_interrupts(int irq_lines)
{
	int	i;
	
	for (i = 0; i < 16; i++) {
		if (irq_lines & (1 << i))
			free_irq(i);
	}
}

/*
 * This routine figures out the correct timeout for a particular IRQ.
 * It uses the smallest timeout of all of the serial ports in a
 * particular interrupt chain.
 */
static void figure_IRQ_timeout(int irq)
{
	struct	async_struct	*info;
	int	timeout = 6000;	/* 60 seconds === a long time :-) */

	info = IRQ_ports[irq];
	if (!info) {
		IRQ_timeout[irq] = 6000;
		return;
	}
	while (info) {
		if (info->timeout < timeout)
			timeout = info->timeout;
		info = info->next_port;
	}
	if (!irq)
		timeout = timeout / 2;
	IRQ_timeout[irq] = timeout ? timeout : 1;
}

static int startup(struct async_struct * info, int get_irq)
{
	unsigned short ICP;
	unsigned long flags;
	struct sigaction	sa;
	int			retval;

	if (info->flags & ASYNC_INITIALIZED)
		return 0;

	if (!info->port || !info->type) {
		if (info->tty)
			set_bit(TTY_IO_ERROR, &info->tty->flags);
		return 0;
	}

	save_flags(flags); cli();

#ifdef SERIAL_DEBUG_OPEN
	printk("starting up ttys%d (irq %d)...", info->line, info->irq);
#endif

	/*
	 * Allocate the IRQ if necessary
	 */
	if (get_irq && info->irq && !IRQ_ports[info->irq]) {
		sa.sa_handler = rs_interrupt;
		sa.sa_flags = (SA_INTERRUPT);
		sa.sa_mask = 0;
		sa.sa_restorer = NULL;
		retval = irqaction(info->irq,&sa);
		if (retval) {
			restore_flags(flags);
			return retval;
		}
	}

	/*
	 * Clear the FIFO buffers and disable them
	 * (they will be reenabled in change_speed())
	 */
	if (info->type == PORT_16550A) {
		serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR |
					     UART_FCR_CLEAR_XMIT));
		info->xmit_fifo_size = 16;
	} else
		info->xmit_fifo_size = 1;

	/*
	 * Clear the interrupt registers.
	 */
	(void)serial_inp(info, UART_LSR);
	(void)serial_inp(info, UART_RX);
	(void)serial_inp(info, UART_IIR);
	(void)serial_inp(info, UART_MSR);

	/*
	 * Now, initialize the UART 
	 */
	serial_outp(info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
	if (info->flags & ASYNC_FOURPORT) 
		serial_outp(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
	else
		serial_outp(info, UART_MCR,
			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
	
	/*
	 * Finally, enable interrupts
	 */
#ifdef ISR_HACK
	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
	serial_outp(info, UART_IER, info->IER);	/* enable interrupts */
#else
	info->IER = (UART_IER_MSI | UART_IER_RLSI |
		     UART_IER_THRI | UART_IER_RDI);
	serial_outp(info, UART_IER, info->IER);	/* enable all intrs */
#endif
	if (info->flags & ASYNC_FOURPORT) {
		/* Enable interrupts on the AST Fourport board */
		ICP = (info->port & 0xFE0) | 0x01F;
		outb_p(0x80, ICP);
		(void) inb_p(ICP);
	}

	/*
	 * And clear the interrupt registers again for luck.
	 */
	(void)serial_inp(info, UART_LSR);
	(void)serial_inp(info, UART_RX);
	(void)serial_inp(info, UART_IIR);
	(void)serial_inp(info, UART_MSR);

	if (info->tty)
		clear_bit(TTY_IO_ERROR, &info->tty->flags);
	/*
	 * Set up parity check flag
	 */
	if (info->tty && info->tty->termios && I_INPCK(info->tty))
		info->read_status_mask = (UART_LSR_OE | UART_LSR_BI |
					  UART_LSR_FE | UART_LSR_PE);
	else
		info->read_status_mask = (UART_LSR_OE | UART_LSR_BI |
					  UART_LSR_FE);

	/*
	 * Insert serial port into IRQ chain.
	 */
	info->prev_port = 0;
	info->next_port = IRQ_ports[info->irq];
	if (info->next_port)
		info->next_port->prev_port = info;
	IRQ_ports[info->irq] = info;
	figure_IRQ_timeout(info->irq);

	/*
	 * Set up serial timers...
	 */
	IRQ_active |= 1 << info->irq;
	figure_RS_timer();

	/*
	 * and set the speed of the serial port
	 */
	change_speed(info->line);

	info->flags |= ASYNC_INITIALIZED;
	restore_flags(flags);
	return 0;
}

/*
 * This routine will shutdown a serial port; interrupts are disabled, and
 * DTR is dropped if the hangup on close termio flag is on.
 */
static void shutdown(struct async_struct * info, int do_free_irq)
{
	unsigned long flags;

	if (!(info->flags & ASYNC_INITIALIZED))
		return;

#ifdef SERIAL_DEBUG_OPEN
	printk("Shutting down serial port %d (irq %d)....", info->line,
	       info->irq);
#endif
	
	save_flags(flags); cli(); /* Disable interrupts */
	
	/*
	 * First unlink the serial port from the IRQ chain...
	 */
	if (info->next_port)
		info->next_port->prev_port = info->prev_port;
	if (info->prev_port)
		info->prev_port->next_port = info->next_port;
	else
		IRQ_ports[info->irq] = info->next_port;
	figure_IRQ_timeout(info->irq);
	
	/*
	 * Free the IRQ, if necessary
	 */
	if (do_free_irq && info->irq && !IRQ_ports[info->irq])
		free_irq(info->irq);
	
	info->IER = 0;
	serial_outp(info, UART_IER, 0x00);	/* disable all intrs */
	if (info->flags & ASYNC_FOURPORT) {
		/* reset interrupts on the AST Fourport board */
		(void) inb((info->port & 0xFE0) | 0x01F);
	}
	if (info->tty && !(info->tty->termios->c_cflag & HUPCL))
		serial_outp(info, UART_MCR, UART_MCR_DTR);
	else
		/* reset DTR,RTS,OUT_2 */		
		serial_outp(info, UART_MCR, 0x00);

	/* disable FIFO's */	
	serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR |
				     UART_FCR_CLEAR_XMIT));
	(void)serial_in(info, UART_RX);    /* read data port to reset things */
	
	if (info->tty)
		set_bit(TTY_IO_ERROR, &info->tty->flags);
	
	info->flags &= ~ASYNC_INITIALIZED;
	restore_flags(flags);
}

/*
 * This routine is called to set the UART divisor registers to match
 * the specified baud rate for a serial port.
 */
static void change_speed(unsigned int line)
{
	struct async_struct * info;
	unsigned short port;
	int	quot = 0;
	unsigned cflag,cval,mcr,fcr;
	int	i;

	if (line >= NR_PORTS)
		return;
	info = rs_table + line;
	if (!info->tty || !info->tty->termios)
		return;
	cflag = info->tty->termios->c_cflag;
	if (!(port = info->port))
		return;
	i = cflag & CBAUD;
	if (i == 15) {
		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
			i += 1;
		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
			i += 2;
		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
			quot = info->custom_divisor;
	}
	if (quot) {
		info->timeout = ((info->xmit_fifo_size*HZ*15*quot) /
				 info->baud_base) + 2;
	} else if (baud_table[i] == 134) {
		quot = (2*info->baud_base / 269);
		info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
	} else if (baud_table[i]) {
		quot = info->baud_base / baud_table[i];
		info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
	} else {
		quot = 0;
		info->timeout = 0;
	}
	cli();
	mcr = serial_in(info, UART_MCR);
	if (quot) {
		serial_out(info, UART_MCR, mcr | UART_MCR_DTR);
	} else {
		serial_out(info, UART_MCR, mcr & ~UART_MCR_DTR);
		sti();
		return;
	}
	sti();
	/* byte size and parity */
	cval = cflag & (CSIZE | CSTOPB);
	cval >>= 4;
	if (cflag & PARENB)
		cval |= UART_LCR_PARITY;
	if (!(cflag & PARODD))
		cval |= UART_LCR_EPAR;
	if (info->type == PORT_16550A) {
		if ((info->baud_base / quot) < 2400)
			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
		else
			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
	} else
		fcr = 0;
	
	cli();
	serial_outp(info, UART_LCR, cval | UART_LCR_DLAB);	/* set DLAB */
	serial_outp(info, UART_DLL, quot & 0xff);	/* LS of divisor */
	serial_outp(info, UART_DLM, quot >> 8);		/* MS of divisor */
	serial_outp(info, UART_LCR, cval);		/* reset DLAB */
	serial_outp(info, UART_FCR, fcr); 	/* set fcr */
	sti();
}

/*
 * ------------------------------------------------------------
 * rs_write() and friends
 * ------------------------------------------------------------
 */

/*
 * This routine is used by rs_write to restart transmitter interrupts,
 * which are disabled after we have a transmitter interrupt which went
 * unacknowledged because we had run out of data to transmit.
 * 
 * Note: this subroutine must be called with the interrupts *off*
 */
static inline void restart_port(struct async_struct *info)
{
	struct tty_queue * queue;
	int head, tail, count;
	
	if (!info)
		return;

	if (serial_inp(info, UART_LSR) & UART_LSR_THRE) {
		if (info->x_char) {
			serial_outp(info, UART_TX, info->x_char);
			info->x_char = 0;
		} else {
			queue = &info->tty->write_q;
			head = queue->head;
			tail = queue->tail;
			count = info->xmit_fifo_size;
			while (count--) {
				if (tail == head)
					break;
				serial_outp(info, UART_TX, queue->buf[tail++]);
				tail &= TTY_BUF_SIZE-1;
			}
			queue->tail = tail;
		}
	}
}	

/*
 * This routine gets called when tty_write has put something into
 * the write_queue.  
 */
void rs_write(struct tty_struct * tty)
{
	struct async_struct *info;

	if (!tty || tty->stopped || tty->hw_stopped)
		return;
	info = rs_table + DEV_TO_SL(tty->line);
	cli();

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美精品一区二区三区在线 | 狠狠狠色丁香婷婷综合久久五月| 久久99精品久久久久久久久久久久 | 99久久99久久精品免费看蜜桃| 欧美日韩国产小视频| 欧美激情在线一区二区| 日韩av一级电影| 欧美综合亚洲图片综合区| 久久久美女毛片| 蜜桃av一区二区| 欧美日韩一区不卡| 亚洲精品免费播放| 99久久国产免费看| 国产日产精品1区| 精品一区二区免费视频| 3d动漫精品啪啪1区2区免费| 亚洲乱码日产精品bd| 成人教育av在线| 国产欧美一区二区精品性| 六月丁香综合在线视频| 6080亚洲精品一区二区| 偷窥少妇高潮呻吟av久久免费| 91毛片在线观看| 中文字幕佐山爱一区二区免费| 成人在线视频一区二区| 久久久久一区二区三区四区| 久久精品国产77777蜜臀| 日韩三级.com| 久久精品久久精品| 欧美成人一区二区三区| 蜜臀国产一区二区三区在线播放 | 日韩国产精品91| 欧美肥妇毛茸茸| 欧美a一区二区| 日韩一区二区免费电影| 手机精品视频在线观看| 91精品久久久久久久99蜜桃| 午夜a成v人精品| 欧美一卡在线观看| 美女看a上一区| 欧美精品一区二区不卡| 国产专区欧美精品| 国产日韩精品一区二区浪潮av| 国产黄人亚洲片| 国产精品久久久久久久久晋中| 成人av网在线| 亚洲成人av福利| 日韩写真欧美这视频| 国内一区二区视频| 国产精品久久夜| 欧美视频一区二| 免费高清成人在线| 久久综合色天天久久综合图片| 国产精品一区二区免费不卡| 中文字幕一区二区三区av| 色香蕉成人二区免费| 日韩中文字幕91| 国产亚洲一本大道中文在线| 91视频国产资源| 日本网站在线观看一区二区三区| 精品久久人人做人人爱| 99久久久久久| 蜜臀av性久久久久蜜臀aⅴ流畅| 久久天天做天天爱综合色| 91蝌蚪国产九色| 久久精品理论片| 亚洲男人都懂的| 日韩视频123| 91性感美女视频| 美女视频黄久久| 亚洲麻豆国产自偷在线| 精品99一区二区三区| 91亚洲永久精品| 久久99国产精品久久| 中文字幕日韩一区| 亚洲精品在线观看网站| 在线精品国精品国产尤物884a| 老司机精品视频一区二区三区| 亚洲欧美中日韩| 日韩精品一区二区三区视频在线观看| 成人av午夜影院| 精品一区二区三区久久久| 伊人开心综合网| 精品国产一区二区三区四区四| 欧洲日韩一区二区三区| 国产91精品露脸国语对白| 美女视频一区二区| 亚洲国产一区在线观看| 中文字幕乱码一区二区免费| 欧美一区二区三区的| 日本韩国欧美三级| 成人污视频在线观看| 九九热在线视频观看这里只有精品| 亚洲精品视频免费看| 国产午夜久久久久| 精品蜜桃在线看| 欧美高清一级片在线| 91福利视频网站| 91在线免费看| 成人午夜碰碰视频| 国产精品综合视频| 国产在线精品一区二区不卡了| 五月综合激情日本mⅴ| 亚洲日本在线视频观看| 中文字幕在线不卡国产视频| 久久久国产一区二区三区四区小说 | www.视频一区| 成人激情小说乱人伦| 风间由美性色一区二区三区| 国内不卡的二区三区中文字幕| 精品一区二区三区在线观看国产 | 国产盗摄女厕一区二区三区| 激情成人综合网| 国产自产视频一区二区三区| 久草热8精品视频在线观看| 日本麻豆一区二区三区视频| 午夜精品在线看| 免费在线视频一区| 久久成人免费日本黄色| 久久91精品国产91久久小草 | 日韩欧美资源站| 精品久久99ma| 精品国产髙清在线看国产毛片 | 国产目拍亚洲精品99久久精品| 久久久久久久性| 国产精品国产自产拍高清av| 亚洲欧美另类小说视频| 一区二区在线免费观看| 亚洲国产视频网站| 日韩高清不卡一区二区三区| 看电影不卡的网站| 国产精品一区二区久激情瑜伽| 成人精品国产一区二区4080| 一本高清dvd不卡在线观看| 欧美撒尿777hd撒尿| 欧美精品123区| 久久精品视频网| 综合欧美一区二区三区| 亚洲成人先锋电影| 国产在线精品一区二区夜色 | 欧美午夜精品一区二区三区| 91精品国产一区二区三区蜜臀| 2021国产精品久久精品| 中文字幕日韩av资源站| 午夜精品福利在线| 国产丶欧美丶日本不卡视频| 91成人在线观看喷潮| 久久综合av免费| 亚洲精品亚洲人成人网在线播放| 日韩高清国产一区在线| 国产大陆a不卡| 欧美日韩精品一区视频| 久久精品一区二区三区四区| 亚洲激情在线激情| 久久精品久久精品| 色婷婷精品久久二区二区蜜臀av| 91精品国产欧美一区二区18| 亚洲国产高清在线| 视频一区二区三区在线| 成人激情视频网站| 日韩视频免费直播| 樱桃视频在线观看一区| 国产裸体歌舞团一区二区| 欧美日韩亚洲国产综合| 日本一区二区动态图| 蜜桃av一区二区三区| 日本电影欧美片| 国产三级久久久| 青青青爽久久午夜综合久久午夜| 成人免费视频一区| 精品国产乱码久久久久久蜜臀| 亚洲精品国产成人久久av盗摄| 国产精品自拍在线| 日韩丝袜情趣美女图片| 亚洲国产成人91porn| www.亚洲色图.com| 久久精品视频在线免费观看| 日本欧美大码aⅴ在线播放| 色综合欧美在线视频区| 久久久久久久网| 九九精品视频在线看| 3d成人h动漫网站入口| 亚洲第一精品在线| 在线观看亚洲精品| 亚洲乱码日产精品bd| 97精品久久久午夜一区二区三区| 久久精品亚洲精品国产欧美kt∨ | 波多野结衣亚洲| 精品国产一区a| 久久国产剧场电影| 日韩欧美激情一区| 奇米精品一区二区三区四区 | 欧美在线你懂得| 亚洲欧美视频在线观看| 成人黄色网址在线观看| 国产精品久久免费看| 国产91丝袜在线播放0| 国产午夜精品美女毛片视频| 久久狠狠亚洲综合| 亚洲精品一区二区三区精华液|