summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/cy/cy.c32
-rw-r--r--sys/dev/cy/cy_isa.c32
-rw-r--r--sys/dev/rc/rc.c20
-rw-r--r--sys/dev/sio/sio.c32
-rw-r--r--sys/i386/isa/cy.c32
-rw-r--r--sys/i386/isa/rc.c20
-rw-r--r--sys/i386/isa/sio.c32
-rw-r--r--sys/isa/sio.c32
-rw-r--r--sys/kern/tty.c140
-rw-r--r--sys/sys/tty.h3
10 files changed, 126 insertions, 249 deletions
diff --git a/sys/dev/cy/cy.c b/sys/dev/cy/cy.c
index bd8d7a49..7852317 100644
--- a/sys/dev/cy/cy.c
+++ b/sys/dev/cy/cy.c
@@ -27,7 +27,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: cy.c,v 1.12 1995/07/29 04:05:53 bde Exp $
+ * $Id: cy.c,v 1.13 1995/07/29 08:33:06 bde Exp $
*/
#include "cy.h"
@@ -1599,31 +1599,6 @@ repeat:
if (incc <= 0 || !(tp->t_state & TS_ISOPEN))
continue;
/*
- * XXX only do this when we bypass ttyinput.
- */
- if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
- && (com->state & CS_RTS_IFLOW || tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK)
- /*
- * XXX - need flow control for all line disciplines.
- * Only have it in standard one now.
- */
- && linesw[tp->t_line].l_rint == ttyinput) {
- int putc_status = 0;
-
- if ((tp->t_iflag & IXOFF
- && tp->t_cc[VSTOP] != _POSIX_VDISABLE
- && (putc_status = putc(tp->t_cc[VSTOP],
- &tp->t_outq)) == 0)
- || com->state & CS_RTS_IFLOW) {
- tp->t_state |= TS_TBLOCK;
- ttstart(tp);
- if (putc_status != 0)
- /* Try again later. */
- tp->t_state &= ~TS_TBLOCK;
- }
- }
- /*
* Avoid the grotesquely inefficient lineswitch routine
* (ttyinput) in "raw" mode. It usually takes about 450
* instructions (that's without canonical processing or echo!).
@@ -1631,6 +1606,11 @@ repeat:
* call overhead).
*/
if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
+ if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
+ && (com->state & CS_RTS_IFLOW
+ || tp->t_iflag & IXOFF)
+ && !(tp->t_state & TS_TBLOCK))
+ ttyblock(tp);
tk_nin += incc;
tk_rawcc += incc;
tp->t_rawcc += incc;
diff --git a/sys/dev/cy/cy_isa.c b/sys/dev/cy/cy_isa.c
index bd8d7a49..7852317 100644
--- a/sys/dev/cy/cy_isa.c
+++ b/sys/dev/cy/cy_isa.c
@@ -27,7 +27,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: cy.c,v 1.12 1995/07/29 04:05:53 bde Exp $
+ * $Id: cy.c,v 1.13 1995/07/29 08:33:06 bde Exp $
*/
#include "cy.h"
@@ -1599,31 +1599,6 @@ repeat:
if (incc <= 0 || !(tp->t_state & TS_ISOPEN))
continue;
/*
- * XXX only do this when we bypass ttyinput.
- */
- if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
- && (com->state & CS_RTS_IFLOW || tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK)
- /*
- * XXX - need flow control for all line disciplines.
- * Only have it in standard one now.
- */
- && linesw[tp->t_line].l_rint == ttyinput) {
- int putc_status = 0;
-
- if ((tp->t_iflag & IXOFF
- && tp->t_cc[VSTOP] != _POSIX_VDISABLE
- && (putc_status = putc(tp->t_cc[VSTOP],
- &tp->t_outq)) == 0)
- || com->state & CS_RTS_IFLOW) {
- tp->t_state |= TS_TBLOCK;
- ttstart(tp);
- if (putc_status != 0)
- /* Try again later. */
- tp->t_state &= ~TS_TBLOCK;
- }
- }
- /*
* Avoid the grotesquely inefficient lineswitch routine
* (ttyinput) in "raw" mode. It usually takes about 450
* instructions (that's without canonical processing or echo!).
@@ -1631,6 +1606,11 @@ repeat:
* call overhead).
*/
if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
+ if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
+ && (com->state & CS_RTS_IFLOW
+ || tp->t_iflag & IXOFF)
+ && !(tp->t_state & TS_TBLOCK))
+ ttyblock(tp);
tk_nin += incc;
tk_rawcc += incc;
tp->t_rawcc += incc;
diff --git a/sys/dev/rc/rc.c b/sys/dev/rc/rc.c
index ec93d68..1e9f666 100644
--- a/sys/dev/rc/rc.c
+++ b/sys/dev/rc/rc.c
@@ -664,24 +664,12 @@ repeat:
if (icnt <= 0 || !(tp->t_state & TS_ISOPEN))
goto done1;
- if ( linesw[tp->t_line].l_rint == ttyinput
- && ((rc->rc_flags & RC_RTSFLOW) || (tp->t_iflag & IXOFF))
- && !(tp->t_state & TS_TBLOCK)
- && (tp->t_rawq.c_cc + icnt) > RB_I_HIGH_WATER) {
- int queue_full = 0;
-
- if ((tp->t_iflag & IXOFF) &&
- tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
- (queue_full = putc(tp->t_cc[VSTOP], &tp->t_outq)) == 0 ||
- (rc->rc_flags & RC_RTSFLOW)) {
- tp->t_state |= TS_TBLOCK;
- ttstart(tp);
- if (queue_full) /* try again */
- tp->t_state &= ~TS_TBLOCK;
- }
- }
if ( (tp->t_state & TS_CAN_BYPASS_L_RINT)
&& !(tp->t_state & TS_LOCAL)) {
+ if ((tp->t_rawq.c_cc + icnt) >= RB_I_HIGH_WATER
+ && ((rc->rc_flags & RC_RTSFLOW) || (tp->t_iflag & IXOFF))
+ && !(tp->t_state & TS_TBLOCK))
+ ttyblock(tp);
tk_nin += icnt;
tk_rawcc += icnt;
tp->t_rawcc += icnt;
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c
index a428eeb..97f9dd7 100644
--- a/sys/dev/sio/sio.c
+++ b/sys/dev/sio/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.106 1995/07/29 04:05:57 bde Exp $
+ * $Id: sio.c,v 1.107 1995/07/29 08:33:13 bde Exp $
*/
#include "sio.h"
@@ -1548,31 +1548,6 @@ repeat:
if (incc <= 0 || !(tp->t_state & TS_ISOPEN))
continue;
/*
- * XXX only do this when we bypass ttyinput.
- */
- if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
- && (com->state & CS_RTS_IFLOW || tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK)
- /*
- * XXX - need flow control for all line disciplines.
- * Only have it in standard one now.
- */
- && linesw[tp->t_line].l_rint == ttyinput) {
- int putc_status = 0;
-
- if ((tp->t_iflag & IXOFF
- && tp->t_cc[VSTOP] != _POSIX_VDISABLE
- && (putc_status = putc(tp->t_cc[VSTOP],
- &tp->t_outq)) == 0)
- || com->state & CS_RTS_IFLOW) {
- tp->t_state |= TS_TBLOCK;
- ttstart(tp);
- if (putc_status != 0)
- /* Try again later. */
- tp->t_state &= ~TS_TBLOCK;
- }
- }
- /*
* Avoid the grotesquely inefficient lineswitch routine
* (ttyinput) in "raw" mode. It usually takes about 450
* instructions (that's without canonical processing or echo!).
@@ -1580,6 +1555,11 @@ repeat:
* call overhead).
*/
if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
+ if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
+ && (com->state & CS_RTS_IFLOW
+ || tp->t_iflag & IXOFF)
+ && !(tp->t_state & TS_TBLOCK))
+ ttyblock(tp);
tk_nin += incc;
tk_rawcc += incc;
tp->t_rawcc += incc;
diff --git a/sys/i386/isa/cy.c b/sys/i386/isa/cy.c
index bd8d7a49..7852317 100644
--- a/sys/i386/isa/cy.c
+++ b/sys/i386/isa/cy.c
@@ -27,7 +27,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: cy.c,v 1.12 1995/07/29 04:05:53 bde Exp $
+ * $Id: cy.c,v 1.13 1995/07/29 08:33:06 bde Exp $
*/
#include "cy.h"
@@ -1599,31 +1599,6 @@ repeat:
if (incc <= 0 || !(tp->t_state & TS_ISOPEN))
continue;
/*
- * XXX only do this when we bypass ttyinput.
- */
- if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
- && (com->state & CS_RTS_IFLOW || tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK)
- /*
- * XXX - need flow control for all line disciplines.
- * Only have it in standard one now.
- */
- && linesw[tp->t_line].l_rint == ttyinput) {
- int putc_status = 0;
-
- if ((tp->t_iflag & IXOFF
- && tp->t_cc[VSTOP] != _POSIX_VDISABLE
- && (putc_status = putc(tp->t_cc[VSTOP],
- &tp->t_outq)) == 0)
- || com->state & CS_RTS_IFLOW) {
- tp->t_state |= TS_TBLOCK;
- ttstart(tp);
- if (putc_status != 0)
- /* Try again later. */
- tp->t_state &= ~TS_TBLOCK;
- }
- }
- /*
* Avoid the grotesquely inefficient lineswitch routine
* (ttyinput) in "raw" mode. It usually takes about 450
* instructions (that's without canonical processing or echo!).
@@ -1631,6 +1606,11 @@ repeat:
* call overhead).
*/
if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
+ if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
+ && (com->state & CS_RTS_IFLOW
+ || tp->t_iflag & IXOFF)
+ && !(tp->t_state & TS_TBLOCK))
+ ttyblock(tp);
tk_nin += incc;
tk_rawcc += incc;
tp->t_rawcc += incc;
diff --git a/sys/i386/isa/rc.c b/sys/i386/isa/rc.c
index ec93d68..1e9f666 100644
--- a/sys/i386/isa/rc.c
+++ b/sys/i386/isa/rc.c
@@ -664,24 +664,12 @@ repeat:
if (icnt <= 0 || !(tp->t_state & TS_ISOPEN))
goto done1;
- if ( linesw[tp->t_line].l_rint == ttyinput
- && ((rc->rc_flags & RC_RTSFLOW) || (tp->t_iflag & IXOFF))
- && !(tp->t_state & TS_TBLOCK)
- && (tp->t_rawq.c_cc + icnt) > RB_I_HIGH_WATER) {
- int queue_full = 0;
-
- if ((tp->t_iflag & IXOFF) &&
- tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
- (queue_full = putc(tp->t_cc[VSTOP], &tp->t_outq)) == 0 ||
- (rc->rc_flags & RC_RTSFLOW)) {
- tp->t_state |= TS_TBLOCK;
- ttstart(tp);
- if (queue_full) /* try again */
- tp->t_state &= ~TS_TBLOCK;
- }
- }
if ( (tp->t_state & TS_CAN_BYPASS_L_RINT)
&& !(tp->t_state & TS_LOCAL)) {
+ if ((tp->t_rawq.c_cc + icnt) >= RB_I_HIGH_WATER
+ && ((rc->rc_flags & RC_RTSFLOW) || (tp->t_iflag & IXOFF))
+ && !(tp->t_state & TS_TBLOCK))
+ ttyblock(tp);
tk_nin += icnt;
tk_rawcc += icnt;
tp->t_rawcc += icnt;
diff --git a/sys/i386/isa/sio.c b/sys/i386/isa/sio.c
index a428eeb..97f9dd7 100644
--- a/sys/i386/isa/sio.c
+++ b/sys/i386/isa/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.106 1995/07/29 04:05:57 bde Exp $
+ * $Id: sio.c,v 1.107 1995/07/29 08:33:13 bde Exp $
*/
#include "sio.h"
@@ -1548,31 +1548,6 @@ repeat:
if (incc <= 0 || !(tp->t_state & TS_ISOPEN))
continue;
/*
- * XXX only do this when we bypass ttyinput.
- */
- if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
- && (com->state & CS_RTS_IFLOW || tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK)
- /*
- * XXX - need flow control for all line disciplines.
- * Only have it in standard one now.
- */
- && linesw[tp->t_line].l_rint == ttyinput) {
- int putc_status = 0;
-
- if ((tp->t_iflag & IXOFF
- && tp->t_cc[VSTOP] != _POSIX_VDISABLE
- && (putc_status = putc(tp->t_cc[VSTOP],
- &tp->t_outq)) == 0)
- || com->state & CS_RTS_IFLOW) {
- tp->t_state |= TS_TBLOCK;
- ttstart(tp);
- if (putc_status != 0)
- /* Try again later. */
- tp->t_state &= ~TS_TBLOCK;
- }
- }
- /*
* Avoid the grotesquely inefficient lineswitch routine
* (ttyinput) in "raw" mode. It usually takes about 450
* instructions (that's without canonical processing or echo!).
@@ -1580,6 +1555,11 @@ repeat:
* call overhead).
*/
if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
+ if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
+ && (com->state & CS_RTS_IFLOW
+ || tp->t_iflag & IXOFF)
+ && !(tp->t_state & TS_TBLOCK))
+ ttyblock(tp);
tk_nin += incc;
tk_rawcc += incc;
tp->t_rawcc += incc;
diff --git a/sys/isa/sio.c b/sys/isa/sio.c
index a428eeb..97f9dd7 100644
--- a/sys/isa/sio.c
+++ b/sys/isa/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.106 1995/07/29 04:05:57 bde Exp $
+ * $Id: sio.c,v 1.107 1995/07/29 08:33:13 bde Exp $
*/
#include "sio.h"
@@ -1548,31 +1548,6 @@ repeat:
if (incc <= 0 || !(tp->t_state & TS_ISOPEN))
continue;
/*
- * XXX only do this when we bypass ttyinput.
- */
- if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
- && (com->state & CS_RTS_IFLOW || tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK)
- /*
- * XXX - need flow control for all line disciplines.
- * Only have it in standard one now.
- */
- && linesw[tp->t_line].l_rint == ttyinput) {
- int putc_status = 0;
-
- if ((tp->t_iflag & IXOFF
- && tp->t_cc[VSTOP] != _POSIX_VDISABLE
- && (putc_status = putc(tp->t_cc[VSTOP],
- &tp->t_outq)) == 0)
- || com->state & CS_RTS_IFLOW) {
- tp->t_state |= TS_TBLOCK;
- ttstart(tp);
- if (putc_status != 0)
- /* Try again later. */
- tp->t_state &= ~TS_TBLOCK;
- }
- }
- /*
* Avoid the grotesquely inefficient lineswitch routine
* (ttyinput) in "raw" mode. It usually takes about 450
* instructions (that's without canonical processing or echo!).
@@ -1580,6 +1555,11 @@ repeat:
* call overhead).
*/
if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
+ if (tp->t_rawq.c_cc + incc >= RB_I_HIGH_WATER
+ && (com->state & CS_RTS_IFLOW
+ || tp->t_iflag & IXOFF)
+ && !(tp->t_state & TS_TBLOCK))
+ ttyblock(tp);
tk_nin += incc;
tk_rawcc += incc;
tp->t_rawcc += incc;
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 66947ae..940a75b 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)tty.c 8.8 (Berkeley) 1/21/94
- * $Id: tty.c,v 1.59 1995/07/30 12:39:16 bde Exp $
+ * $Id: tty.c,v 1.60 1995/07/30 13:52:56 bde Exp $
*/
/*-
@@ -95,9 +95,9 @@
static int proc_compare __P((struct proc *p1, struct proc *p2));
static int ttnread __P((struct tty *));
-static void ttyblock __P((struct tty *tp));
static void ttyecho __P((int, struct tty *tp));
static void ttyrubo __P((struct tty *, int));
+static void ttyunblock __P((struct tty *tp));
/*
* Table with character classes and parity. The 8th bit indicates parity,
@@ -177,6 +177,14 @@ char const char_type[] = {
#define CLR(t, f) (t) &= ~(f)
#define ISSET(t, f) ((t) & (f))
+/*
+ * Input control starts when we would not be able to fit the maximum
+ * contents of the ping-pong buffers and finishes when we would be able
+ * to fit that much plus 1/8 more.
+ */
+#define I_HIGH_WATER (TTYHOG - 2 * 256) /* XXX */
+#define I_LOW_WATER ((TTYHOG - 2 * 256) * 7 / 8) /* XXX */
+
#undef MAX_INPUT /* XXX wrong in <sys/syslimits.h> */
#define MAX_INPUT TTYHOG
@@ -285,9 +293,21 @@ ttyinput(c, tp)
}
++tk_nin;
+ /*
+ * Block further input iff:
+ * current input > threshold AND input is available to user program
+ * AND input flow control is enabled and not yet invoked.
+ * The 3 is slop for PARMRK.
+ */
+ iflag = tp->t_iflag;
+ if (tp->t_rawq.c_cc + tp->t_canq.c_cc > I_HIGH_WATER - 3 &&
+ (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
+ (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
+ !ISSET(tp->t_state, TS_TBLOCK))
+ ttyblock(tp);
+
/* Handle exceptional conditions (break, parity, framing). */
cc = tp->t_cc;
- iflag = tp->t_iflag;
err = (ISSET(c, TTY_ERRORMASK));
if (err) {
CLR(c, TTY_ERRORMASK);
@@ -317,11 +337,7 @@ parmrk:
c = 0;
}
}
- /*
- * In tandem mode, check high water mark.
- */
- if (ISSET(iflag, IXOFF) || ISSET(tp->t_cflag, CRTS_IFLOW))
- ttyblock(tp);
+
if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
CLR(c, 0x80);
if (!ISSET(lflag, EXTPROC)) {
@@ -1109,6 +1125,7 @@ ttyflush(tp, rw)
register int s;
s = spltty();
+again:
if (rw & FWRITE)
CLR(tp->t_state, TS_TTSTOP);
#ifdef sun4c /* XXX */
@@ -1123,25 +1140,33 @@ ttyflush(tp, rw)
tp->t_rocol = 0;
CLR(tp->t_state, TS_LOCAL);
ttwakeup(tp);
+ if (ISSET(tp->t_state, TS_TBLOCK)) {
+ ttyunblock(tp);
+ if (ISSET(tp->t_iflag, IXOFF)) {
+ /*
+ * XXX wait a bit in the hope that the stop
+ * character (if any) will go out. Waiting
+ * isn't good since it allows races. This
+ * will be fixed when the stop character is
+ * put in a special queue. Don't bother with
+ * the checks in ttywait() since the timeout
+ * will save us.
+ */
+ SET(tp->t_state, TS_SO_OCOMPLETE);
+ ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
+ "ttyfls", hz / 10);
+ /*
+ * Don't try sending the stop character again.
+ */
+ CLR(tp->t_state, TS_TBLOCK);
+ goto again;
+ }
+ }
}
if (rw & FWRITE) {
FLUSHQ(&tp->t_outq);
ttwwakeup(tp);
}
- if ((rw & FREAD) &&
- ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
- int queue_full = 0;
-
- if (ISSET(tp->t_iflag, IXOFF) &&
- tp->t_cc[VSTART] != _POSIX_VDISABLE &&
- (queue_full = putc(tp->t_cc[VSTART], &tp->t_outq)) == 0 ||
- ISSET(tp->t_cflag, CRTS_IFLOW)) {
- CLR(tp->t_state, TS_TBLOCK);
- ttstart(tp);
- if (queue_full) /* try again */
- SET(tp->t_state, TS_TBLOCK);
- }
- }
splx(s);
}
@@ -1168,34 +1193,37 @@ ttychars(tp)
}
/*
- * Send stop character on input overflow.
+ * Handle input high water. Send stop character for the IXOFF case. Turn
+ * on our input flow control bit and propagate the changes to the driver.
+ * XXX the stop character should be put in a special high priority queue.
*/
-static void
+void
ttyblock(tp)
- register struct tty *tp;
+ struct tty *tp;
{
- register int total;
- total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
- /*
- * Block further input iff: current input > threshold
- * AND input is available to user program.
- */
- if (total >= TTYHOG / 2 &&
- !ISSET(tp->t_state, TS_TBLOCK) &&
- (!ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0)) {
- int queue_full = 0;
-
- if (ISSET(tp->t_iflag, IXOFF) &&
- tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
- (queue_full = putc(tp->t_cc[VSTOP], &tp->t_outq)) == 0 ||
- ISSET(tp->t_cflag, CRTS_IFLOW)) {
- SET(tp->t_state, TS_TBLOCK);
- ttstart(tp);
- if (queue_full) /* try again */
- CLR(tp->t_state, TS_TBLOCK);
- }
- }
+ SET(tp->t_state, TS_TBLOCK);
+ if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
+ putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
+ CLR(tp->t_state, TS_TBLOCK); /* try again later */
+ ttstart(tp);
+}
+
+/*
+ * Handle input low water. Send start character for the IXOFF case. Turn
+ * off our input flow control bit and propagate the changes to the driver.
+ * XXX the start character should be put in a special high priority queue.
+ */
+static void
+ttyunblock(tp)
+ struct tty *tp;
+{
+
+ CLR(tp->t_state, TS_TBLOCK);
+ if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
+ putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
+ SET(tp->t_state, TS_TBLOCK); /* try again later */
+ ttstart(tp);
}
void
@@ -1590,26 +1618,18 @@ slowcase:
break;
first = 0;
}
+
+out:
/*
* Look to unblock input now that (presumably)
* the input queue has gone down.
*/
-out:
s = spltty();
- if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
- int queue_full = 0;
-
- if (ISSET(tp->t_iflag, IXOFF) &&
- cc[VSTART] != _POSIX_VDISABLE &&
- (queue_full = putc(cc[VSTART], &tp->t_outq)) == 0 ||
- ISSET(tp->t_cflag, CRTS_IFLOW)) {
- CLR(tp->t_state, TS_TBLOCK);
- ttstart(tp);
- if (queue_full) /* try again */
- SET(tp->t_state, TS_TBLOCK);
- }
- }
+ if (ISSET(tp->t_state, TS_TBLOCK) &&
+ tp->t_rawq.c_cc + tp->t_canq.c_cc <= I_LOW_WATER)
+ ttyunblock(tp);
splx(s);
+
return (error);
}
diff --git a/sys/sys/tty.h b/sys/sys/tty.h
index 121926f..fb6c977 100644
--- a/sys/sys/tty.h
+++ b/sys/sys/tty.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)tty.h 8.6 (Berkeley) 1/21/94
- * $Id: tty.h,v 1.25 1995/07/29 13:40:13 bde Exp $
+ * $Id: tty.h,v 1.26 1995/07/30 12:39:42 bde Exp $
*/
#ifndef _SYS_TTY_H_
@@ -241,6 +241,7 @@ int ttstart __P((struct tty *tp));
void ttwakeup __P((struct tty *tp));
int ttwrite __P((struct tty *tp, struct uio *uio, int flag));
void ttwwakeup __P((struct tty *tp));
+void ttyblock __P((struct tty *tp));
void ttychars __P((struct tty *tp));
int ttycheckoutq __P((struct tty *tp, int wait));
int ttyclose __P((struct tty *tp));
OpenPOWER on IntegriCloud