* Paul Mackerras (paulus@cs.anu.edu.au).
*/
-/* $Id: if_ppp.c,v 1.5 1995/08/16 01:36:38 paulus Exp $ */
+/* $Id: if_ppp.c,v 1.6 1995/10/27 03:34:42 paulus Exp $ */
/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
#include "ppp.h"
#endif
void pppattach __P((void));
-int pppioctl __P((struct ppp_softc *sc, int cmd, caddr_t data, int flag,
+int pppioctl __P((struct ppp_softc *sc, u_long cmd, caddr_t data, int flag,
struct proc *));
int pppoutput __P((struct ifnet *ifp, struct mbuf *m0,
struct sockaddr *dst, struct rtentry *rtp));
-int pppsioctl __P((struct ifnet *ifp, int cmd, caddr_t data));
+int pppsioctl __P((struct ifnet *ifp, u_long cmd, caddr_t data));
void pppintr __P((void));
static void ppp_requeue __P((struct ppp_softc *));
bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN);
#endif
}
- netisrs[NETISR_PPP] = ppp_intr;
+ netisrs[NETISR_PPP] = pppintr;
}
/*
int
pppioctl(sc, cmd, data, flag, p)
struct ppp_softc *sc;
+ u_long cmd;
caddr_t data;
- int cmd, flag;
+ int flag;
struct proc *p;
{
int s, error, flags, mru, nb, npx;
* a compressor or decompressor.
*/
error = 0;
- s = splnet();
if (odp->transmit) {
+ s = splnet();
if (sc->sc_xc_state != NULL)
(*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
sc->sc_xcomp = *cp;
}
splimp();
sc->sc_flags &= ~SC_COMP_RUN;
+ splx(s);
} else {
+ s = splnet();
if (sc->sc_rc_state != NULL)
(*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
sc->sc_rcomp = *cp;
}
splimp();
sc->sc_flags &= ~SC_DECOMP_RUN;
+ splx(s);
}
- splx(s);
return (error);
}
if (sc->sc_flags & SC_DEBUG)
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
if (npi->mode != sc->sc_npmode[npx]) {
- s = splimp();
+ s = splnet();
sc->sc_npmode[npx] = npi->mode;
if (npi->mode != NPMODE_QUEUE) {
ppp_requeue(sc);
break;
case PPPIOCGIDLE:
- s = splimp();
+ s = splnet();
t = time.tv_sec;
((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent;
((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv;
int
pppsioctl(ifp, cmd, data)
register struct ifnet *ifp;
- int cmd;
+ u_long cmd;
caddr_t data;
{
struct proc *p = curproc; /* XXX */
/*
* Put the packet on the appropriate queue.
*/
- s = splimp(); /* splnet should be OK now */
+ s = splnet();
if (mode == NPMODE_QUEUE) {
/* XXX we should limit the number of packets on this queue */
*sc->sc_npqtail = m0;
sc->sc_npqtail = &m0->m_nextpkt;
} else {
ifq = (m0->m_flags & M_HIGHPRI)? &sc->sc_fastq: &ifp->if_snd;
- if (IF_QFULL(ifq)) {
+ if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) {
IF_DROP(ifq);
splx(s);
sc->sc_if.if_oerrors++;
/*
* After a change in the NPmode for some NP, move packets from the
* npqueue to the send queue or the fast queue as appropriate.
- * Should be called at splimp (actually splnet would probably suffice).
+ * Should be called at splnet.
*/
static void
ppp_requeue(sc)
}
/*
- * Get a packet to send. This procedure is intended to be called
- * at spltty()/splimp(), so it takes little time. If there isn't
- * a packet waiting to go out, it schedules a software interrupt
- * to prepare a new packet; the device start routine gets called
- * again when a packet is ready.
+ * Get a packet to send. This procedure is intended to be called at
+ * spltty or splimp, so it takes little time. If there isn't a packet
+ * waiting to go out, it schedules a software interrupt to prepare a
+ * new packet; the device start routine gets called again when a
+ * packet is ready.
*/
struct mbuf *
ppp_dequeue(sc)
&& (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head))
ppp_outpkt(sc);
for (;;) {
+ s = splimp();
IF_DEQUEUE(&sc->sc_rawq, m);
+ splx(s);
if (m == NULL)
break;
ppp_inproc(sc, m);
--m->m_len;
}
- s = splimp();
sc->sc_togo = m;
(*sc->sc_start)(sc);
- splx(s);
}
#ifdef PPP_COMPRESS
/*
* Process a received PPP packet, doing decompression as necessary.
+ * Should be called at splnet.
*/
#define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \
TYPE_UNCOMPRESSED_TCP)
sc->sc_if.if_ipackets++;
if (sc->sc_flags & SC_LOG_INPKT) {
+ ilen = 0;
+ for (mp = m; mp != NULL; mp = mp->m_next)
+ ilen += mp->m_len;
printf("ppp%d: got %d bytes\n", sc->sc_if.if_unit, ilen);
pppdumpm(m);
}
* Paul Mackerras (paulus@cs.anu.edu.au).
*/
-/* $Id: ppp_tty.c,v 1.3 1995/08/16 01:36:40 paulus Exp $ */
+/* $Id: ppp_tty.c,v 1.4 1995/10/27 03:34:44 paulus Exp $ */
/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
#include "ppp.h"
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,
+int ppptioctl __P((struct tty *tp, u_long cmd, caddr_t data, int flag,
struct proc *));
int pppinput __P((int c, struct tty *tp));
int pppstart __P((struct tty *tp));
/*
* 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
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
+ 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));
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().
*/
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) {
{
int s;
- s = splimp();
+ s = spltty();
if (sc->sc_outm) {
m_freem(sc->sc_outm);
sc->sc_outm = NULL;
* Loop waiting for input, checking that nothing disasterous
* happens in the meantime.
*/
- s = splimp();
+ s = spltty();
for (;;) {
if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
splx(s);
}
if (sc->sc_inq.ifq_head != NULL)
break;
- if ((tp->t_state & TS_CONNECTED) == 0 && (tp->t_state & TS_ISOPEN)) {
+ 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 */
}
splx(s);
return (EWOULDBLOCK);
}
- error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH, "pppin", 0);
+ error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, "ttyin", 0);
if (error) {
splx(s);
return error;
struct sockaddr dst;
int len, error;
- if ((tp->t_state & TS_CONNECTED) == 0)
+ if ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
return 0; /* wrote 0 bytes */
if (tp->t_line != PPPDISC)
return (EINVAL);
int
ppptioctl(tp, cmd, data, flag, p)
struct tty *tp;
+ u_long cmd;
caddr_t data;
- int cmd, flag;
+ int flag;
struct proc *p;
{
struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
/*
* This gets called from pppoutput when a new packet is
- * put on a queue.
+ * put on a queue, at splnet.
*/
static void
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)
int n, s, ndone, done, idle;
struct mbuf *m2;
- if ((tp->t_state & TS_CONNECTED) == 0
+ 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);
struct tty *tp = (struct tty *) sc->sc_devp;
int s;
- s = splimp();
+ s = spltty();
sc->sc_flags &= ~SC_TIMEOUT;
pppstart(tp);
splx(s);
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) {
if (sc == NULL || tp != (struct tty *) sc->sc_devp)
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