summaryrefslogtreecommitdiffstats
path: root/sys/net/if_sl.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1995-03-30 20:43:32 +0000
committerache <ache@FreeBSD.org>1995-03-30 20:43:32 +0000
commit7948beb4ea63bd1694e90447a7c0e40e93d6ce28 (patch)
tree8b7a337e4edd9c47e801b5ac7b5c6068917bd218 /sys/net/if_sl.c
parent183b7355f6228af73ec9662cf32f4d12c7693793 (diff)
downloadFreeBSD-src-7948beb4ea63bd1694e90447a7c0e40e93d6ce28.zip
FreeBSD-src-7948beb4ea63bd1694e90447a7c0e40e93d6ce28.tar.gz
This sl enhancement helps to keep serial line (modem) connection alive.
It is common case when modem hangs with carier on but don't receive anything from another side. This thing commonly healed with hangup and redialing. Enhancements below allows to determine when such action is needed and inform attach program with SIGURG signal. There two ioctls set: outfill and keepalive, used from both sides of connection. Outfill repeatedly sends FRAME_END with specified timeout (i.e. 40 seconds). It is needed to get input on other side even if no user activity on slip line currently. Keepalive checks FRAME_ENDs from other side, and if no one got in specified timeout (i.e. 60 seconds, max modem retrain time), send SIGURG to attach program. I plan to add code to slattach to handle this thing too. Reviewed by: wollman
Diffstat (limited to 'sys/net/if_sl.c')
-rw-r--r--sys/net/if_sl.c91
1 files changed, 89 insertions, 2 deletions
diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c
index 77dfa05..fc407cd 100644
--- a/sys/net/if_sl.c
+++ b/sys/net/if_sl.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)if_sl.c 8.6 (Berkeley) 2/1/94
- * $Id: if_sl.c,v 1.13 1995/03/16 18:14:27 bde Exp $
+ * $Id: if_sl.c,v 1.14 1995/03/20 19:20:43 wollman Exp $
*/
/*
@@ -182,6 +182,8 @@ struct sl_softc sl_softc[NSL];
static int slinit __P((struct sl_softc *));
static struct mbuf *sl_btom __P((struct sl_softc *, int));
+static void sl_keepalive __P((struct sl_softc *));
+static void sl_outfill __P((struct sl_softc *));
#define ttyerrio ((int (*) __P((struct tty *, struct uio *, int)))enodev)
@@ -320,7 +322,16 @@ slclose(tp,flag)
tp->t_line = 0;
sc = (struct sl_softc *)tp->t_sc;
if (sc != NULL) {
+ if (sc->sc_outfill) {
+ sc->sc_outfill = 0;
+ untimeout((timeout_func_t) sl_outfill, (caddr_t) sc);
+ }
+ if (sc->sc_keepalive) {
+ sc->sc_keepalive = 0;
+ untimeout((timeout_func_t) sl_keepalive, (caddr_t) sc);
+ }
if_down(&sc->sc_if);
+ sc->sc_flags = 0;
sc->sc_ttyp = NULL;
tp->t_sc = NULL;
MCLFREE((caddr_t)(sc->sc_ep - SLBUFSIZE));
@@ -346,15 +357,49 @@ sltioctl(tp, cmd, data, flag, p)
struct proc *p;
{
struct sl_softc *sc = (struct sl_softc *)tp->t_sc;
+ int s;
+ s = splimp();
switch (cmd) {
case SLIOCGUNIT:
*(int *)data = sc->sc_if.if_unit;
break;
+ case SLIOCSKEEPAL:
+ sc->sc_keepalive = *(u_int *)data * hz;
+ if (sc->sc_keepalive) {
+ sc->sc_flags |= SC_KEEPALIVE;
+ timeout((timeout_func_t) sl_keepalive, (caddr_t) sc, sc->sc_keepalive);
+ } else {
+ sc->sc_flags &= ~SC_KEEPALIVE;
+ untimeout((timeout_func_t) sl_keepalive, (caddr_t) sc);
+ }
+ break;
+
+ case SLIOCGKEEPAL:
+ *(int *)data = sc->sc_keepalive / hz;
+ break;
+
+ case SLIOCSOUTFILL:
+ sc->sc_outfill = *(u_int *)data * hz;
+ if (sc->sc_outfill) {
+ sc->sc_flags |= SC_OUTWAIT;
+ timeout((timeout_func_t) sl_outfill, (caddr_t) sc, sc->sc_outfill);
+ } else {
+ sc->sc_flags &= ~SC_OUTWAIT;
+ untimeout((timeout_func_t) sl_outfill, (caddr_t) sc);
+ }
+ break;
+
+ case SLIOCGOUTFILL:
+ *(int *)data = sc->sc_outfill / hz;
+ break;
+
default:
- return (-1);
+ splx(s);
+ return (ENOTTY);
}
+ splx(s);
return (0);
}
@@ -448,6 +493,8 @@ slstart(tp)
* it would.
*/
if (tp->t_outq.c_cc != 0) {
+ if (sc != NULL)
+ sc->sc_flags &= ~SC_OUTWAIT;
(*tp->t_oproc)(tp);
if (tp->t_outq.c_cc > SLIP_HIWAT)
return 0;
@@ -470,6 +517,7 @@ slstart(tp)
splx(s);
if (m == NULL)
return 0;
+ sc->sc_flags &= ~SC_OUTWAIT;
/*
* We do the header compression here rather than in sloutput
@@ -728,6 +776,7 @@ slinput(c, tp)
return 0;
case FRAME_END:
+ sc->sc_flags &= ~SC_KEEPALIVE;
if(sc->sc_flags & SC_ERROR) {
sc->sc_flags &= ~SC_ERROR;
goto newpack;
@@ -901,4 +950,42 @@ slioctl(ifp, cmd, data)
splx(s);
return (error);
}
+
+static void sl_keepalive (sc)
+ struct sl_softc *sc;
+{
+ if (sc->sc_keepalive) {
+ if (sc->sc_flags & SC_KEEPALIVE)
+ pgsignal (sc->sc_ttyp->t_pgrp, SIGURG, 1);
+ else
+ sc->sc_flags |= SC_KEEPALIVE;
+ timeout ((timeout_func_t) sl_keepalive, (caddr_t) sc, sc->sc_keepalive);
+ } else {
+ sc->sc_flags &= ~SC_KEEPALIVE;
+ untimeout ((timeout_func_t) sl_keepalive, (caddr_t) sc);
+ }
+}
+
+static void sl_outfill (sc)
+ struct sl_softc *sc;
+{
+ register struct tty *tp = sc->sc_ttyp;
+ int s;
+
+ if (sc->sc_outfill && tp != NULL) {
+ if (sc->sc_flags & SC_OUTWAIT) {
+ s = splimp ();
+ ++sc->sc_if.if_obytes;
+ putc(FRAME_END, tp->t_out);
+ (*tp->t_oproc)(tp);
+ splx (s);
+ } else
+ sc->sc_flags |= SC_OUTWAIT;
+ timeout ((timeout_func_t) sl_outfill, (caddr_t) sc, sc->sc_outfill);
+ } else {
+ sc->sc_flags &= ~SC_OUTWAIT;
+ untimeout ((timeout_func_t) sl_outfill, (caddr_t) sc);
+ }
+}
+
#endif
OpenPOWER on IntegriCloud