⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mxpcdrv.c

📁 isa总线设备
💻 C
📖 第 1 页 / 共 5 页
字号:
	while ( 1 ) {	    irqbits = inb(port->vector) & port->vectormask;	    if ( irqbits == port->vectormask )			break;	    handled = 1;	    for ( i=0, bits=1; i<max; i++, irqbits |= bits, bits <<= 1 ) {		if ( irqbits == port->vectormask )		   	break;		if ( bits & irqbits )		    continue;		info = port + i;		// following add by Victor Yu. 09-13-2002		iir = inb(info->base+UART_IIR);		if ( iir & UART_IIR_NO_INT )			continue;		iir &= MOXA_MUST_IIR_MASK;		if ( !info->tty ) {			status = inb(info->base+UART_LSR);			outb(0x27, info->base+UART_FCR);			inb(info->base+UART_MSR);			continue;		}		// above add by Victor Yu. 09-13-2002		/* mask by Victor Yu. 09-13-2002		if ( !info->tty ||		     (inb(info->base + UART_IIR) & UART_IIR_NO_INT) )		    continue;		*/		/* mask by Victor Yu. 09-02-2002		status = inb(info->base + UART_LSR) & info->read_status_mask;		*/		// following add by Victor Yu. 09-02-2002		status = inb(info->base+UART_LSR);		if ( info->IsMoxaMustChipFlag ) {			/*			if ( (status & 0x02) && !(status & 0x01) ) {				outb(info->base+UART_FCR,  0x23);				continue;			}			*/			if ( iir == MOXA_MUST_IIR_GDA ||			     iir == MOXA_MUST_IIR_RDA ||			     iir == MOXA_MUST_IIR_RTO ||			     iir == MOXA_MUST_IIR_LSR )				mxpcdrv_receive_chars(info, &status);		} else {		// above add by Victor Yu. 09-02-2002			status &= info->read_status_mask;			if ( status & UART_LSR_DR )			    mxpcdrv_receive_chars(info, &status);		}		msr = inb(info->base + UART_MSR);		if ( msr & UART_MSR_ANY_DELTA )		    mxpcdrv_check_modem_status(info, msr);		// following add by Victor Yu. 09-13-2002		if ( info->IsMoxaMustChipFlag ) {			if ( iir == 0x02 )				mxpcdrv_transmit_chars(info);		} else {		// above add by Victor Yu. 09-13-2002			if ( status & UART_LSR_THRE ) {/* 8-2-99 by William			    if ( info->x_char || (info->xmit_cnt > 0) )*/				mxpcdrv_transmit_chars(info);			}		}	    }	    if ( pass_counter++ > MXPCDRV_ISR_PASS_LIMIT ) {#if 0		printk("MOXA PC104 Communication Module driver interrupt loop break\n");#endif		break;	/* Prevent infinite loops */	    }	}irq_stop:	return IRQ_RETVAL(handled);}#if defined (_SCREEN_INFO_H) || (LINUX_VERSION_CODE > VERSION_CODE(2,6,15))static void mxpcdrv_receive_chars(struct mxpcdrv_struct *info,					 int *status){	struct tty_struct *	tty = info->tty;	unsigned char		ch, gdl;	int			ignored = 0;	int			cnt = 0;	int			count;	int 			recv_room;	int			max = 256;	unsigned long		flags;        count = 0;	// following add by Victor Yu. 09-02-2002	if ( info->IsMoxaMustChipFlag != MOXA_OTHER_UART) {		if ( *status & UART_LSR_SPECIAL ) {			goto intr_old;		}		// following add by Victor Yu. 02-11-2004		//if ( info->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID &&		//     (*status & MOXA_MUST_LSR_RERR) )		//	goto intr_old;		// above add by Victor Yu. 02-14-2004		if(*status & MOXA_MUST_LSR_RERR)			goto intr_old;		gdl = inb(info->base+MOXA_MUST_GDL_REGISTER);				if ( info->IsMoxaMustChipFlag == MOXA_MUST_HARDWARE_ID ) // add by Victor Yu. 02-11-2004			gdl &= MOXA_MUST_GDL_MASK;				while ( gdl-- ) {		    	ch = inb(info->base + UART_RX);			if(cnt>=TTY_FLIPBUF_SIZE)				continue;	    		count++;			tty_insert_flip_char(tty, ch, 0);			cnt++;		}		goto end_intr;	}intr_old:	// above add by Victor Yu. 09-02-2002	do {	    if(max-- <0) 		break;	    ch = inb(info->base + UART_RX);	    if(cnt>=TTY_FLIPBUF_SIZE)		continue;	    // following add by Victor Yu. 09-02-2002	    if ( info->IsMoxaMustChipFlag && (*status&UART_LSR_OE) /*&& !(*status&UART_LSR_DR)*/ )		outb(0x23, info->base+UART_FCR);	    *status &= info->read_status_mask;	    // above add by Victor Yu. 09-02-2002	    if ( *status & info->ignore_status_mask ) {		if ( ++ignored > 100 )		    break;	    } else {		count++;		if ( *status & UART_LSR_SPECIAL ) {		    if ( *status & UART_LSR_BI ) {			flags = TTY_BREAK;#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))			info->icount.brk++;#endif			if ( info->flags & ASYNC_SAK )			    do_SAK(tty);		    } else if ( *status & UART_LSR_PE ) {			flags = TTY_PARITY;#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))			info->icount.parity++;#endif		    } else if ( *status & UART_LSR_FE ) {			flags = TTY_FRAME;#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))			info->icount.frame++;#endif		    } else if ( *status & UART_LSR_OE ) {			flags = TTY_OVERRUN;#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))			info->icount.overrun++;#endif		    } else			flags = TTY_BREAK;		} else			flags = 0;		tty_insert_flip_char(tty, ch, flags);		cnt++;	    }		    // following add by Victor Yu. 09-02-2002	    if ( info->IsMoxaMustChipFlag )		break;	    // above add by Victor Yu. 09-02-2002	    /* mask by Victor Yu. 09-02-2002	    *status = inb(info->base + UART_LSR) & info->read_status_mask;	    */	    // following add by Victor Yu. 09-02-2002	    *status = inb(info->base+UART_LSR);	    // above add by Victor Yu. 09-02-2002	} while ( *status & UART_LSR_DR );end_intr:	// add by Victor Yu. 09-02-2002	mxvar_log.rxcnt[info->port] += cnt;	recv_room = tty->receive_room;	if(recv_room < (128*2)){		set_bit(TTY_THROTTLED, &tty->flags);		mxpcdrv_stoprx(tty);	}	tty_flip_buffer_push(tty);}#elsestatic void mxpcdrv_receive_chars(struct mxpcdrv_struct *info,					 int *status){	struct tty_struct *	tty = info->tty;	unsigned char		ch, gdl;	int			ignored = 0;	int			cnt = 0;	int			count;	int 			recv_room;	unsigned char           *cp;	char                    *fp;	int			max = 256;	//MX_LOCK(&info->slock);#if 0	recv_room = tty->ldisc.receive_room(tty);	if((recv_room == 0) && (!info->ldisc_stop_rx)){		//mxser_throttle(tty);       	mxpcdrv_stoprx(tty);		//return;	}#endif		        cp = tty->flip.char_buf;        fp = tty->flip.flag_buf;        count = 0;	// following add by Victor Yu. 09-02-2002	if ( info->IsMoxaMustChipFlag ) {		if ( *status & UART_LSR_SPECIAL ) {			goto intr_old;		}		// following add by Victor Yu. 02-11-2004		//if ( info->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID &&		//     (*status & MOXA_MUST_LSR_RERR) )		//	goto intr_old;		// above add by Victor Yu. 02-14-2004		if(*status & MOXA_MUST_LSR_RERR)			goto intr_old;		gdl = inb(info->base+MOXA_MUST_GDL_REGISTER);		//gdl &= MOXA_MUST_GDL_MASK;				if ( info->IsMoxaMustChipFlag == MOXA_MUST_HARDWARE_ID ) // add by Victor Yu. 02-11-2004			gdl &= MOXA_MUST_GDL_MASK;#if 0				if(gdl >= recv_room) {			if(!info->ldisc_stop_rx){				//mxser_throttle(tty);        			mxpcdrv_stoprx(tty);			}			//return;		}		#endif				while ( gdl-- ) {	    	ch = inb(info->base + UART_RX);			/*if ( tty->flip.count >= TTY_FLIPBUF_SIZE )		    		break;			tty->flip.count++;			*tty->flip.char_buf_ptr++ = ch;*/			if(cnt>=TTY_FLIPBUF_SIZE)				continue;				    		count++;			*cp++ = ch;	    	*fp++ = 0;			cnt++;		}		goto end_intr;	}intr_old:	// above add by Victor Yu. 09-02-2002	do {	    if(max-- <0) 		break;	    ch = inb(info->base + UART_RX);			if(cnt>=TTY_FLIPBUF_SIZE)				continue;	    // following add by Victor Yu. 09-02-2002	    if ( info->IsMoxaMustChipFlag && (*status&UART_LSR_OE) /*&& !(*status&UART_LSR_DR)*/ )		outb(0x23, info->base+UART_FCR);	    *status &= info->read_status_mask;	    // above add by Victor Yu. 09-02-2002	    if ( *status & info->ignore_status_mask ) {		if ( ++ignored > 100 )		    break;	    } else {		/*if ( tty->flip.count >= TTY_FLIPBUF_SIZE )		    break;		tty->flip.count++;		*/		count++;		if ( *status & UART_LSR_SPECIAL ) {		    if ( *status & UART_LSR_BI ) {			*fp++ = TTY_BREAK;/* added by casper 1/11/2000 */#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))			info->icount.brk++;#endif/* */			if ( info->flags & ASYNC_SAK )			    do_SAK(tty);		    } else if ( *status & UART_LSR_PE ) {			*fp++ = TTY_PARITY;/* added by casper 1/11/2000 */#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))			info->icount.parity++;#endif/* */		    } else if ( *status & UART_LSR_FE ) {			*fp++ = TTY_FRAME;/* added by casper 1/11/2000 */#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))			info->icount.frame++;#endif/* */		    } else if ( *status & UART_LSR_OE ) {			*fp++ = TTY_OVERRUN;/* added by casper 1/11/2000 */#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))			info->icount.overrun++;#endif/* */		    } else			*fp++ = 0;		} else		    *fp++ = 0;		    *cp++ = ch;		cnt++;#if 0		if(cnt>=recv_room){			if(!info->ldisc_stop_rx){				//mxser_throttle(tty);        			mxpcdrv_stoprx(tty);			}			break;		}#endif		}		    // following add by Victor Yu. 09-02-2002	    if ( info->IsMoxaMustChipFlag )		break;	    // above add by Victor Yu. 09-02-2002	    /* mask by Victor Yu. 09-02-2002	    *status = inb(info->base + UART_LSR) & info->read_status_mask;	    */	    // following add by Victor Yu. 09-02-2002	    *status = inb(info->base+UART_LSR);	    // above add by Victor Yu. 09-02-2002	} while ( *status & UART_LSR_DR );end_intr:	// add by Victor Yu. 09-02-2002	mxvar_log.rxcnt[info->port] += cnt;/* added by casper 1/11/2000 */#if 0#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))	info->icount.rx += cnt;	/* add by Victor Yu. 05-14-2002 following */	clear_bit(TTY_DONT_FLIP, &tty->flags);	/* add by Victor Yu. 05-14-2002 above */	tty_flip_buffer_push(tty);#else	queue_task_irq_off(&tty->flip.tqueue, &tq_timer);#endif#endif#if 1 	tty->ldisc.receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);	//MX_UNLOCK(&info->slock);	recv_room = tty->ldisc.receive_room(tty);	if(recv_room < (128*2)){		set_bit(TTY_THROTTLED, &tty->flags);		mxpcdrv_stoprx(tty);	}#endif/* */}#endif//_SCREEN_INFO_Hstatic void mxpcdrv_transmit_chars(struct mxpcdrv_struct *info){	int	count, cnt;	if ( !info)		return;	if ( info->x_char ) {	    outb(info->x_char, info->base + UART_TX);	    info->x_char = 0;	    mxvar_log.txcnt[info->port]++;/* added by casper 1/11/2000 */#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))	    info->icount.tx++;#endif/* */	    return;	}if ( info->xmit_buf == 0 )	return;	if(info->xmit_cnt==0){		if ( info->xmit_cnt < WAKEUP_CHARS ) {			set_bit(MXPCDRV_EVENT_TXLOW,&info->event);			MXQ_TASK();		}		return;	}#if 1	if (/*(info->xmit_cnt <= 0) ||*/ info->tty->stopped ||	    (info->tty->hw_stopped && (info->type != PORT_16550A) &&(!info->IsMoxaMustChipFlag))) {		info->IER &= ~UART_IER_THRI;		outb(info->IER, info->base + UART_IER);		return;	}#endif	cnt = info->xmit_cnt;	count = info->xmit_fifo_size;	do {	    outb(info->xmit_buf[info->xmit_tail++], info->base + UART_TX);	    info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);	    if ( --info->xmit_cnt <= 0 )		break;	} while ( --count > 0 );	mxvar_log.txcnt[info->port] += (cnt - info->xmit_cnt);/* added by casper 1/11/2000 */#if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0))        info->icount.tx += (cnt - info->xmit_cnt);#endif/* */	if ( info->xmit_cnt < WAKEUP_CHARS ) {		set_bit(MXPCDRV_EVENT_TXLOW,&info->event);		MXQ_TASK();	}#if 0	if (info->xmit_cnt <= 0) {		info->IER &= ~UART_IER_THRI;		outb(info->IER, info->base + UART_IER);	}#en

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -