X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=ultrix%2Fppp_tty.c;h=5753e78a6e7b3747bd951f89aa7b3db0a095cd3f;hp=a1d8af783042932994d5a0fa0e85adbdb3fcaec0;hb=4ffa02f546c16059afd48a31735f00f5c58f3ae0;hpb=a471bdc20d7f993fc126b765c8c3dacbc902fa68 diff --git a/ultrix/ppp_tty.c b/ultrix/ppp_tty.c index a1d8af7..5753e78 100644 --- a/ultrix/ppp_tty.c +++ b/ultrix/ppp_tty.c @@ -73,7 +73,7 @@ * Robert Olsson and Paul Mackerras. */ -/* $Id: ppp_tty.c,v 1.3 1994/12/08 00:32:59 paulus Exp $ */ +/* $Id: ppp_tty.c,v 1.5 1995/05/02 02:48:32 paulus Exp $ */ /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ #include "ppp.h" @@ -122,6 +122,7 @@ static u_short pppfcs __P((u_short fcs, u_char *cp, int len)); static void pppasyncstart __P((struct ppp_softc *)); static void pppasyncctlp __P((struct ppp_softc *)); static void pppasyncrelinq __P((struct ppp_softc *)); +static void ppp_timeout __P((void *)); static void pppgetm __P((struct ppp_softc *sc)); static void pppdumpb __P((u_char *b, int l)); static void ppplogchar __P((struct ppp_softc *, int)); @@ -256,6 +257,10 @@ pppasyncrelinq(sc) m_freem(sc->sc_m); sc->sc_m = NULL; } + if (sc->sc_flags & SC_TIMEOUT) { + untimeout(ppp_timeout, (void *) sc); + sc->sc_flags &= ~SC_TIMEOUT; + } splx(s); } @@ -273,22 +278,31 @@ pppread(tp, uio, flag) register int s; int error = 0; - if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0) - return 0; /* end of file */ - if (sc == NULL || tp != (struct tty *) sc->sc_devp) + if (sc == NULL) return 0; + /* + * Loop waiting for input, checking that nothing disasterous + * happens in the meantime. + */ s = splimp(); - while (sc->sc_inq.ifq_head == NULL && tp->t_line == PPPDISC) { + for (;;) { + if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) { + splx(s); + return 0; + } + if (sc->sc_inq.ifq_head != NULL) + break; + if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0 + && (tp->t_state & TS_ISOPEN)) { + splx(s); + return 0; /* end of file */ + } if (tp->t_state & (TS_ASYNC | TS_NBIO)) { splx(s); return (EWOULDBLOCK); } sleep((caddr_t) &tp->t_rawq, TTIPRI); } - if (tp->t_line != PPPDISC) { - splx(s); - return (-1); - } /* Pull place-holder byte out of canonical queue */ getc(&tp->t_canq); @@ -511,30 +525,18 @@ pppstart(tp) register struct mbuf *m; register int len; register u_char *start, *stop, *cp; - int n, s, ndone, done; + int n, s, ndone, done, idle; struct mbuf *m2; - if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0) { - /* sorry, I can't talk now */ - return; - } - if (sc == NULL || tp != (struct tty *) sc->sc_devp) { - (*tp->t_oproc)(tp); - return; - } - - for (;;) { - /* - * If there is more in the output queue, just send it now. - * We are being called in lieu of ttstart and must do what - * it would. - */ - if (CCOUNT(&tp->t_outq) != 0 && tp->t_oproc != NULL) { + if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0 + || sc == NULL || tp != (struct tty *) sc->sc_devp) { + if (tp->t_oproc != NULL) (*tp->t_oproc)(tp); - if (CCOUNT(&tp->t_outq) > PPP_HIWAT) - return; - } + return 0; + } + idle = 0; + while (CCOUNT(&tp->t_outq) < PPP_HIWAT) { /* * See if we have an existing packet partly sent. * If not, get a new packet and start sending it. @@ -546,9 +548,8 @@ pppstart(tp) */ m = ppp_dequeue(sc); if (m == NULL) { - if (tp->t_oproc != NULL) - (*tp->t_oproc)(tp); - return; + idle = 1; + break; } /* @@ -604,6 +605,7 @@ pppstart(tp) len--; } } + /* * If we didn't empty this mbuf, remember where we're up to. * If we emptied the last mbuf, try to add the FCS and closing @@ -645,31 +647,70 @@ pppstart(tp) unputc(&tp->t_outq); break; } + sc->sc_bytessent += q - endseq; } if (!done) { m->m_off += m->m_len - len; m->m_len = len; - sc->sc_outm = m; - if (tp->t_oproc != NULL) - (*tp->t_oproc)(tp); - return; /* can't do any more at the moment */ + break; } /* Finished with this mbuf; free it and move on. */ MFREE(m, m2); - if (m2 == NULL) - break; - m = m2; + if (m == NULL) { + /* Finished a packet */ + sc->sc_if.if_opackets++; + break; + } sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len); } - /* Finished a packet */ - sc->sc_outm = NULL; - sc->sc_bytessent++; /* account for closing flag */ - sc->sc_if.if_opackets++; + /* + * Here we have either finished a packet (m == NULL) + * or filled up the output queue (m != NULL). + */ + sc->sc_outm = m; + if (m) + break; + } + + /* + * If there is stuff in the output queue, send it now. + * We are being called in lieu of ttstart and must do what it would. + */ + if (tp->t_oproc != NULL) + (*tp->t_oproc)(tp); + + /* + * This timeout is needed for operation on a pseudo-tty, + * because the pty code doesn't call pppstart after it has + * drained the t_outq. + */ + if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) { + timeout(ppp_timeout, (void *) sc, 1); + sc->sc_flags |= SC_TIMEOUT; } + + return 0; +} + +/* + * Timeout routine - try to start some more output. + */ +static void +ppp_timeout(x) + void *x; +{ + struct ppp_softc *sc = (struct ppp_softc *) x; + struct tty *tp = (struct tty *) sc->sc_devp; + int s; + + s = splimp(); + sc->sc_flags &= ~SC_TIMEOUT; + pppstart(tp); + splx(s); } /* @@ -714,16 +755,16 @@ pppinput(c, tp) { register struct ppp_softc *sc; struct mbuf *m; - int ilen; + int ilen, s; extern int tk_nin; - tk_nin++; sc = (struct ppp_softc *) tp->t_sc; if (sc == NULL || tp != (struct tty *) sc->sc_devp) - return; + return 0; s = spltty(); - sc->sc_bytesrcvd++; + ++tk_nin; + ++sc->sc_bytesrcvd; c &= 0xff; @@ -761,7 +802,7 @@ pppinput(c, tp) } else sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED); splx(s); - return; + return 0; } if (ilen < PPP_HDRLEN + PPP_FCSLEN) { @@ -772,7 +813,7 @@ pppinput(c, tp) sc->sc_flags |= SC_PKTLOST; } splx(s); - return; + return 0; } /* @@ -796,19 +837,19 @@ pppinput(c, tp) pppgetm(sc); splx(s); - return; + return 0; } if (sc->sc_flags & SC_FLUSH) { if (sc->sc_flags & SC_LOG_FLUSH) ppplogchar(sc, c); splx(s); - return; + return 0; } if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) { splx(s); - return; + return 0; } if (sc->sc_flags & SC_ESCAPED) { @@ -817,7 +858,7 @@ pppinput(c, tp) } else if (c == PPP_ESCAPE) { sc->sc_flags |= SC_ESCAPED; splx(s); - return; + return 0; } /* @@ -905,7 +946,7 @@ pppinput(c, tp) *sc->sc_mp++ = c; sc->sc_fcs = PPP_FCS(sc->sc_fcs, c); splx(s); - return; + return 0; flush: if (!(sc->sc_flags & SC_FLUSH)) { @@ -915,6 +956,7 @@ pppinput(c, tp) ppplogchar(sc, c); } splx(s); + return 0; } #define MAX_DUMP_BYTES 128