X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=ultrix%2Fppp_tty.c;h=40d6cf2a13d391478a9094bb72861fe4bb0ce65e;hp=09b7769bf863798aff6a60a17684fb1e62fdc421;hb=3fca15005a3eb1adb1ac4f94ec3eb6439e2dc865;hpb=9d622390ee952ed05d910054182724a1cb88d9b2 diff --git a/ultrix/ppp_tty.c b/ultrix/ppp_tty.c index 09b7769..40d6cf2 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.4 1994/12/13 03:30:21 paulus Exp $ */ +/* $Id: ppp_tty.c,v 1.6 1995/10/27 04:00:10 paulus Exp $ */ /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ #include "ppp.h" @@ -113,8 +113,7 @@ int pppopen __P((dev_t dev, struct tty *tp)); int pppclose __P((struct tty *tp, int flag)); int pppread __P((struct tty *tp, struct uio *uio, int flag)); int pppwrite __P((struct tty *tp, struct uio *uio, int flag)); -int ppptioctl __P((struct tty *tp, int cmd, caddr_t data, int flag, - struct proc *)); +int ppptioctl __P((struct tty *tp, int cmd, caddr_t data, int flag)); int pppinput __P((int c, struct tty *tp)); int pppstart __P((struct tty *tp)); @@ -162,6 +161,7 @@ static void ppplogchar __P((struct ppp_softc *, int)); /* * Line specific open routine for async tty devices. * Attach the given tty to the first available ppp unit. + * Called from device open routine or ttioctl. */ /* ARGSUSED */ int @@ -176,19 +176,24 @@ pppopen(dev, tp) if (!suser()) return EPERM; + s = spltty(); + if (tp->t_line == PPPDISC) { sc = (struct ppp_softc *) tp->t_sc; - if (sc != NULL && sc->sc_devp == (void *) tp) + if (sc != NULL && sc->sc_devp == (void *) tp) { + splx(s); return (0); + } } - if ((sc = pppalloc(p->p_pid)) == NULL) + if ((sc = pppalloc(p->p_pid)) == NULL) { + splx(s); return ENXIO; + } if (sc->sc_relinq) (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */ - s = splimp(); sc->sc_ilen = 0; sc->sc_m = NULL; bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap)); @@ -205,13 +210,14 @@ pppopen(dev, tp) tp->t_sc = (caddr_t) sc; ttyflush(tp, FREAD | FWRITE); - splx(s); + splx(s); return (0); } /* - * Line specific close routine. + * Line specific close routine, called from device close routine + * and from ttioctl. * Detach the tty from the ppp unit. * Mimics part of ttyclose(). */ @@ -224,8 +230,8 @@ pppclose(tp, flag) struct mbuf *m; int s; - ttywflush(tp); - s = splimp(); /* paranoid; splnet probably ok */ + s = spltty(); + ttyflush(tp, FREAD|FWRITE); tp->t_line = 0; sc = (struct ppp_softc *) tp->t_sc; if (sc != NULL) { @@ -248,7 +254,7 @@ pppasyncrelinq(sc) { int s; - s = splimp(); + s = spltty(); if (sc->sc_outm) { m_freem(sc->sc_outm); sc->sc_outm = NULL; @@ -278,22 +284,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; - s = splimp(); - while (sc->sc_inq.ifq_head == NULL && tp->t_line == PPPDISC) { + /* + * Loop waiting for input, checking that nothing disasterous + * happens in the meantime. + */ + s = spltty(); + 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); @@ -474,7 +489,7 @@ pppfcs(fcs, cp, len) /* * This gets called from pppoutput when a new packet is - * put on a queue. + * put on a queue, at splnet. */ static void pppasyncstart(sc) @@ -483,30 +498,34 @@ pppasyncstart(sc) register struct tty *tp = (struct tty *) sc->sc_devp; int s; - s = splimp(); + s = spltty(); pppstart(tp); splx(s); } /* * This gets called when a received packet is placed on - * the inq. + * the inq, at splnet. */ static void pppasyncctlp(sc) struct ppp_softc *sc; { struct tty *tp; + int s; /* Put a placeholder byte in canq for ttselect()/ttnread(). */ + s = spltty(); tp = (struct tty *) sc->sc_devp; putc(0, &tp->t_canq); ttwakeup(tp); + splx(s); } /* * Start output on async tty interface. Get another datagram * to send from the interface queue and start sending it. + * Called at spltty or higher. */ int pppstart(tp) @@ -523,7 +542,7 @@ pppstart(tp) || sc == NULL || tp != (struct tty *) sc->sc_devp) { if (tp->t_oproc != NULL) (*tp->t_oproc)(tp); - return; + return 0; } idle = 0; @@ -683,6 +702,8 @@ pppstart(tp) timeout(ppp_timeout, (void *) sc, 1); sc->sc_flags |= SC_TIMEOUT; } + + return 0; } /* @@ -696,7 +717,7 @@ ppp_timeout(x) struct tty *tp = (struct tty *) sc->sc_devp; int s; - s = splimp(); + s = spltty(); sc->sc_flags &= ~SC_TIMEOUT; pppstart(tp); splx(s); @@ -713,7 +734,7 @@ pppgetm(sc) int len; int s; - s = splimp(); + s = spltty(); mp = &sc->sc_m; for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){ if ((m = *mp) == NULL) { @@ -749,14 +770,30 @@ pppinput(c, tp) sc = (struct ppp_softc *) tp->t_sc; if (sc == NULL || tp != (struct tty *) sc->sc_devp) - return; + return 0; - s = spltty(); + s = spltty(); /* should be unnecessary */ ++tk_nin; ++sc->sc_bytesrcvd; c &= 0xff; + if (sc->sc_flags & SC_XONXOFF) { + if (c == XOFF) { + if ((tp->t_state & TS_TTSTOP) == 0) { + tp->t_state |= TS_TTSTOP; + (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0); + } + return 0; + } + if (c == XON) { + tp->t_state &= ~TS_TTSTOP; + if (tp->t_oproc != NULL) + (*tp->t_oproc)(tp); + return 0; + } + } + if (c & 0x80) sc->sc_flags |= SC_RCV_B7_1; else @@ -791,7 +828,7 @@ pppinput(c, tp) } else sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED); splx(s); - return; + return 0; } if (ilen < PPP_HDRLEN + PPP_FCSLEN) { @@ -802,7 +839,7 @@ pppinput(c, tp) sc->sc_flags |= SC_PKTLOST; } splx(s); - return; + return 0; } /* @@ -826,19 +863,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) { @@ -847,7 +884,7 @@ pppinput(c, tp) } else if (c == PPP_ESCAPE) { sc->sc_flags |= SC_ESCAPED; splx(s); - return; + return 0; } /* @@ -935,7 +972,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)) { @@ -945,6 +982,7 @@ pppinput(c, tp) ppplogchar(sc, c); } splx(s); + return 0; } #define MAX_DUMP_BYTES 128