📄 mxpcdrv.c
字号:
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 + -