/*************************************************************************** Function: sWriteTxPrioByte Purpose: Write a byte of priority transmit data to a channel Call: sWriteTxPrioByte(ChP,Data) CHANNEL_T *ChP; Ptr to channel structure Byte_t Data; The transmit data byte Return: int: 1 if the bytes is successfully written, otherwise 0. Comments: The priority byte is transmitted before any data in the Tx FIFO. Warnings: No context switches are allowed while executing this function. */ int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data) { Byte_t DWBuf[4]; /* buffer for double word writes */ if(sGetTxCnt(ChP) > 1) /* write it to Tx priority buffer */ { rp_writech2(ChP,_INDX_ADDR,ChP->TxPrioCnt); /* get priority buffer status */ if(rp_readch1(ChP,_INDX_DATA) & PRI_PEND) /* priority buffer busy */ return(0); /* nothing sent */ le16enc(DWBuf,ChP->TxPrioBuf); /* data byte address */ DWBuf[2] = Data; /* data byte value */ DWBuf[3] = 0; /* priority buffer pointer */ rp_writech4(ChP,_INDX_ADDR,le32dec(DWBuf)); /* write it out */ le16enc(DWBuf,ChP->TxPrioCnt); /* Tx priority count address */ DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */ DWBuf[3] = 0; /* priority buffer pointer */ rp_writech4(ChP,_INDX_ADDR,le32dec(DWBuf)); /* write it out */ } else /* write it to Tx FIFO */ { sWriteTxByte(ChP,sGetTxRxDataIO(ChP),Data); } return(1); /* 1 byte sent */ }
/*************************************************************************** Function: sWriteTxPrioByte Purpose: Write a byte of priority transmit data to a channel Call: sWriteTxPrioByte(ChP,Data) CHANNEL_T *ChP; Ptr to channel structure Byte_t Data; The transmit data byte Return: int: 1 if the bytes is successfully written, otherwise 0. Comments: The priority byte is transmitted before any data in the Tx FIFO. Warnings: No context switches are allowed while executing this function. */ int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data) { Byte_t DWBuf[4]; /* buffer for double word writes */ Word_t *WordPtr; /* must be far because Win SS != DS */ crit_enter(); if(sGetTxCnt(ChP) > 1) /* write it to Tx priority buffer */ { rp_writech2(ChP,_INDX_ADDR,ChP->TxPrioCnt); /* get priority buffer status */ if(rp_readch1(ChP,_INDX_DATA) & PRI_PEND) {/* priority buffer busy */ crit_exit(); return(0); /* nothing sent */ } WordPtr = (Word_t *)(&DWBuf[0]); *WordPtr = ChP->TxPrioBuf; /* data byte address */ DWBuf[2] = Data; /* data byte value */ rp_writech4(ChP,_INDX_ADDR,*((DWord_t *)(&DWBuf[0]))); /* write it out */ *WordPtr = ChP->TxPrioCnt; /* Tx priority count address */ DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */ DWBuf[3] = 0; /* priority buffer pointer */ rp_writech4(ChP,_INDX_ADDR,*((DWord_t *)(&DWBuf[0]))); /* write it out */ } else /* write it to Tx FIFO */ { sWriteTxByte(ChP,sGetTxRxDataIO(ChP),Data); } crit_exit(); return(1); /* 1 byte sent */ }
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--; } } }