/*************************************************************************** Function: sFlushRxFIFO Purpose: Flush the Rx FIFO Call: sFlushRxFIFO(ChP) CHANNEL_T *ChP; Ptr to channel structure Return: void Comments: To prevent data from being enqueued or dequeued in the Tx FIFO while it is being flushed the receive processor is stopped and the transmitter is disabled. After these operations a 4 uS delay is done before clearing the pointers to allow the receive processor to stop. These items are handled inside this function. Warnings: No context switches are allowed while executing this function. */ void sFlushRxFIFO(CHANNEL_T *ChP) { int i; Byte_t Ch; /* channel number within AIOP */ int RxFIFOEnabled; /* TRUE if Rx FIFO enabled */ if(sGetRxCnt(ChP) == 0) /* Rx FIFO empty */ return; /* don't need to flush */ RxFIFOEnabled = FALSE; if(ChP->R[0x32] == 0x08) /* Rx FIFO is enabled */ { RxFIFOEnabled = TRUE; sDisRxFIFO(ChP); /* disable it */ for(i=0; i < 2000/200; i++) /* delay 2 uS to allow proc to disable FIFO*/ rp_readch1(ChP,_INT_CHAN); /* depends on bus i/o timing */ } sGetChanStatus(ChP); /* clear any pending Rx errors in chan stat */ Ch = (Byte_t)sGetChanNum(ChP); rp_writech1(ChP,_CMD_REG,Ch | RESRXFCNT); /* apply reset Rx FIFO count */ rp_writech1(ChP,_CMD_REG,Ch); /* remove reset Rx FIFO count */ rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs); /* clear Rx out ptr */ rp_writech2(ChP,_INDX_DATA,0); rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */ rp_writech2(ChP,_INDX_DATA,0); if(RxFIFOEnabled) sEnRxFIFO(ChP); /* enable Rx FIFO */ }
static void rp_do_receive(struct rp_port *rp, struct tty *tp, CHANNEL_t *cp, unsigned int ChanStatus) { unsigned int CharNStat; int ToRecv, ch, err = 0; ToRecv = sGetRxCnt(cp); if(ToRecv == 0) return; /* If status indicates there are errored characters in the FIFO, then enter status mode (a word in FIFO holds characters and status) */ if(ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) { if(!(ChanStatus & STATMODE)) { ChanStatus |= STATMODE; sEnRxStatusMode(cp); } } /* if we previously entered status mode then read down the FIFO one word at a time, pulling apart the character and the status. Update error counters depending on status. */ tty_lock(tp); if(ChanStatus & STATMODE) { while(ToRecv) { CharNStat = rp_readch2(cp,sGetTxRxDataIO(cp)); ch = CharNStat & 0xff; if((CharNStat & STMBREAK) || (CharNStat & STMFRAMEH)) err |= TRE_FRAMING; else if (CharNStat & STMPARITYH) err |= TRE_PARITY; else if (CharNStat & STMRCVROVRH) { rp->rp_overflows++; err |= TRE_OVERRUN; } ttydisc_rint(tp, ch, err); ToRecv--; } /* After emtying FIFO in status mode, turn off status mode */ if(sGetRxCnt(cp) == 0) { sDisRxStatusMode(cp); } } else { ToRecv = sGetRxCnt(cp); while (ToRecv) { ch = rp_readch1(cp,sGetTxRxDataIO(cp)); ttydisc_rint(tp, ch & 0xff, err); ToRecv--; } } ttydisc_rint_done(tp); tty_unlock(tp); }
/* * NOTE: Must be called with tty_token held */ static void rp_do_receive(struct rp_port *rp, struct tty *tp, CHANNEL_t *cp, unsigned int ChanStatus) { unsigned int CharNStat; int ToRecv, wRecv, ch, ttynocopy; ASSERT_LWKT_TOKEN_HELD(&tty_token); ToRecv = sGetRxCnt(cp); if(ToRecv == 0) return; /* If status indicates there are errored characters in the FIFO, then enter status mode (a word in FIFO holds characters and status) */ if(ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) { if(!(ChanStatus & STATMODE)) { ChanStatus |= STATMODE; sEnRxStatusMode(cp); } } /* if we previously entered status mode then read down the FIFO one word at a time, pulling apart the character and the status. Update error counters depending on status. */ if(ChanStatus & STATMODE) { while(ToRecv) { if(tp->t_state & TS_TBLOCK) { break; } CharNStat = rp_readch2(cp,sGetTxRxDataIO(cp)); ch = CharNStat & 0xff; if((CharNStat & STMBREAK) || (CharNStat & STMFRAMEH)) ch |= TTY_FE; else if (CharNStat & STMPARITYH) ch |= TTY_PE; else if (CharNStat & STMRCVROVRH) rp->rp_overflows++; (*linesw[tp->t_line].l_rint)(ch, tp); ToRecv--; } /* After emtying FIFO in status mode, turn off status mode */ if(sGetRxCnt(cp) == 0) { sDisRxStatusMode(cp); } } else { /* * Avoid the grotesquely inefficient lineswitch routine * (ttyinput) in "raw" mode. It usually takes about 450 * instructions (that's without canonical processing or echo!). * slinput is reasonably fast (usually 40 instructions plus * call overhead). */ ToRecv = sGetRxCnt(cp); if ( tp->t_state & TS_CAN_BYPASS_L_RINT ) { if ( ToRecv > RXFIFO_SIZE ) { ToRecv = RXFIFO_SIZE; } wRecv = ToRecv >> 1; if ( wRecv ) { rp_readmultich2(cp,sGetTxRxDataIO(cp),(u_int16_t *)rp->RxBuf,wRecv); } if ( ToRecv & 1 ) { ((unsigned char *)rp->RxBuf)[(ToRecv-1)] = (u_char) rp_readch1(cp,sGetTxRxDataIO(cp)); } tk_nin += ToRecv; tk_rawcc += ToRecv; tp->t_rawcc += ToRecv; ttynocopy = b_to_q((char *)rp->RxBuf, ToRecv, &tp->t_rawq); ttwakeup(tp); } else { while (ToRecv) { if(tp->t_state & TS_TBLOCK) { break; } ch = (u_char) rp_readch1(cp,sGetTxRxDataIO(cp)); crit_enter(); (*linesw[tp->t_line].l_rint)(ch, tp); crit_exit(); ToRecv--; } } }