Workaround IXOFF bug when output queue is full && RTS control is on

This commit is contained in:
Andrey A. Chernov 1995-02-28 23:21:33 +00:00
parent c71243fd9a
commit 5d8619d1f2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=6790
4 changed files with 34 additions and 10 deletions

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)com.c 7.5 (Berkeley) 5/16/91 * from: @(#)com.c 7.5 (Berkeley) 5/16/91
* $Id: sio.c,v 1.68 1995/02/26 02:30:18 bde Exp $ * $Id: sio.c,v 1.69 1995/02/28 00:20:54 pst Exp $
*/ */
#include "sio.h" #include "sio.h"
@ -1531,12 +1531,16 @@ repeat:
* Only have it in standard one now. * Only have it in standard one now.
*/ */
&& linesw[tp->t_line].l_rint == ttyinput) { && linesw[tp->t_line].l_rint == ttyinput) {
int queue_full = 0;
if ((tp->t_iflag & IXOFF) && if ((tp->t_iflag & IXOFF) &&
tp->t_cc[VSTOP] != _POSIX_VDISABLE && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
putc(tp->t_cc[VSTOP], &tp->t_outq) == 0 || (queue_full = putc(tp->t_cc[VSTOP], &tp->t_outq)) == 0 ||
(com->state & CS_RTS_IFLOW)) { (com->state & CS_RTS_IFLOW)) {
tp->t_state |= TS_TBLOCK; tp->t_state |= TS_TBLOCK;
ttstart(tp); ttstart(tp);
if (queue_full) /* try again */
tp->t_state &= ~TS_TBLOCK;
} }
} }
/* /*

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)com.c 7.5 (Berkeley) 5/16/91 * from: @(#)com.c 7.5 (Berkeley) 5/16/91
* $Id: sio.c,v 1.68 1995/02/26 02:30:18 bde Exp $ * $Id: sio.c,v 1.69 1995/02/28 00:20:54 pst Exp $
*/ */
#include "sio.h" #include "sio.h"
@ -1531,12 +1531,16 @@ repeat:
* Only have it in standard one now. * Only have it in standard one now.
*/ */
&& linesw[tp->t_line].l_rint == ttyinput) { && linesw[tp->t_line].l_rint == ttyinput) {
int queue_full = 0;
if ((tp->t_iflag & IXOFF) && if ((tp->t_iflag & IXOFF) &&
tp->t_cc[VSTOP] != _POSIX_VDISABLE && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
putc(tp->t_cc[VSTOP], &tp->t_outq) == 0 || (queue_full = putc(tp->t_cc[VSTOP], &tp->t_outq)) == 0 ||
(com->state & CS_RTS_IFLOW)) { (com->state & CS_RTS_IFLOW)) {
tp->t_state |= TS_TBLOCK; tp->t_state |= TS_TBLOCK;
ttstart(tp); ttstart(tp);
if (queue_full) /* try again */
tp->t_state &= ~TS_TBLOCK;
} }
} }
/* /*

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)com.c 7.5 (Berkeley) 5/16/91 * from: @(#)com.c 7.5 (Berkeley) 5/16/91
* $Id: sio.c,v 1.68 1995/02/26 02:30:18 bde Exp $ * $Id: sio.c,v 1.69 1995/02/28 00:20:54 pst Exp $
*/ */
#include "sio.h" #include "sio.h"
@ -1531,12 +1531,16 @@ repeat:
* Only have it in standard one now. * Only have it in standard one now.
*/ */
&& linesw[tp->t_line].l_rint == ttyinput) { && linesw[tp->t_line].l_rint == ttyinput) {
int queue_full = 0;
if ((tp->t_iflag & IXOFF) && if ((tp->t_iflag & IXOFF) &&
tp->t_cc[VSTOP] != _POSIX_VDISABLE && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
putc(tp->t_cc[VSTOP], &tp->t_outq) == 0 || (queue_full = putc(tp->t_cc[VSTOP], &tp->t_outq)) == 0 ||
(com->state & CS_RTS_IFLOW)) { (com->state & CS_RTS_IFLOW)) {
tp->t_state |= TS_TBLOCK; tp->t_state |= TS_TBLOCK;
ttstart(tp); ttstart(tp);
if (queue_full) /* try again */
tp->t_state &= ~TS_TBLOCK;
} }
} }
/* /*

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)tty.c 8.8 (Berkeley) 1/21/94 * @(#)tty.c 8.8 (Berkeley) 1/21/94
* $Id: tty.c,v 1.33 1995/02/27 19:47:31 ugen Exp $ * $Id: tty.c,v 1.34 1995/02/28 00:21:03 pst Exp $
*/ */
#include "snp.h" #include "snp.h"
@ -1098,12 +1098,16 @@ ttyflush(tp, rw)
} }
if ((rw & FREAD) && if ((rw & FREAD) &&
ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) { ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
int queue_full = 0;
if (ISSET(tp->t_iflag, IXOFF) && if (ISSET(tp->t_iflag, IXOFF) &&
tp->t_cc[VSTART] != _POSIX_VDISABLE && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
putc(tp->t_cc[VSTART], &tp->t_outq) == 0 || (queue_full = putc(tp->t_cc[VSTART], &tp->t_outq)) == 0 ||
ISSET(tp->t_cflag, CRTS_IFLOW)) { ISSET(tp->t_cflag, CRTS_IFLOW)) {
CLR(tp->t_state, TS_TBLOCK); CLR(tp->t_state, TS_TBLOCK);
ttstart(tp); ttstart(tp);
if (queue_full) /* try again */
SET(tp->t_state, TS_TBLOCK);
} }
} }
splx(s); splx(s);
@ -1137,12 +1141,16 @@ ttyblock(tp)
if (total >= TTYHOG / 2 && if (total >= TTYHOG / 2 &&
!ISSET(tp->t_state, TS_TBLOCK) && !ISSET(tp->t_state, TS_TBLOCK) &&
(!ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0)) { (!ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0)) {
int queue_full = 0;
if (ISSET(tp->t_iflag, IXOFF) && if (ISSET(tp->t_iflag, IXOFF) &&
tp->t_cc[VSTOP] != _POSIX_VDISABLE && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
putc(tp->t_cc[VSTOP], &tp->t_outq) == 0 || (queue_full = putc(tp->t_cc[VSTOP], &tp->t_outq)) == 0 ||
ISSET(tp->t_cflag, CRTS_IFLOW)) { ISSET(tp->t_cflag, CRTS_IFLOW)) {
SET(tp->t_state, TS_TBLOCK); SET(tp->t_state, TS_TBLOCK);
ttstart(tp); ttstart(tp);
if (queue_full) /* try again */
CLR(tp->t_state, TS_TBLOCK);
} }
} }
} }
@ -1531,12 +1539,16 @@ read:
*/ */
s = spltty(); s = spltty();
if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) { if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
int queue_full = 0;
if (ISSET(tp->t_iflag, IXOFF) && if (ISSET(tp->t_iflag, IXOFF) &&
cc[VSTART] != _POSIX_VDISABLE && cc[VSTART] != _POSIX_VDISABLE &&
putc(cc[VSTART], &tp->t_outq) == 0 || (queue_full = putc(cc[VSTART], &tp->t_outq)) == 0 ||
ISSET(tp->t_cflag, CRTS_IFLOW)) { ISSET(tp->t_cflag, CRTS_IFLOW)) {
CLR(tp->t_state, TS_TBLOCK); CLR(tp->t_state, TS_TBLOCK);
ttstart(tp); ttstart(tp);
if (queue_full) /* try again */
SET(tp->t_state, TS_TBLOCK);
} }
} }
splx(s); splx(s);