From owner-p4-projects@FreeBSD.ORG Fri Sep 26 17:29:57 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DC8B3106568E; Fri, 26 Sep 2008 17:29:56 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A0D1F106568B for ; Fri, 26 Sep 2008 17:29:56 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 84F068FC1D for ; Fri, 26 Sep 2008 17:29:56 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id m8QHTuQn025961 for ; Fri, 26 Sep 2008 17:29:56 GMT (envelope-from thompsa@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id m8QHTuvq025959 for perforce@freebsd.org; Fri, 26 Sep 2008 17:29:56 GMT (envelope-from thompsa@freebsd.org) Date: Fri, 26 Sep 2008 17:29:56 GMT Message-Id: <200809261729.m8QHTuvq025959@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to thompsa@freebsd.org using -f From: Andrew Thompson To: Perforce Change Reviews Cc: Subject: PERFORCE change 150512 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Sep 2008 17:29:57 -0000 http://perforce.freebsd.org/chv.cgi?CH=150512 Change 150512 by thompsa@thompsa_burger on 2008/09/26 17:29:13 Add in a custom rint routine, we should buffer the input intil the hotchar is seen. In most cases this will be the PPP framing char of 0x7e. Affected files ... .. //depot/projects/mpsafetty/sys/netgraph/ng_tty.c#7 edit Differences ... ==== //depot/projects/mpsafetty/sys/netgraph/ng_tty.c#7 (text+ko) ==== @@ -87,6 +87,7 @@ hook_p hook; /* Netgraph hook */ struct ifqueue outq; /* Queue of outgoing data */ size_t outqlen; /* Number of bytes in outq */ + struct mbuf *m; /* Incoming non-bypass data buffer */ short hotchar; /* Hotchar, or -1 if none */ u_int flags; /* Flags */ }; @@ -110,6 +111,7 @@ static th_getc_inject_t ngt_getc_inject; static th_getc_poll_t ngt_getc_poll; +static th_rint_t ngt_rint; static th_rint_bypass_t ngt_rint_bypass; static th_rint_poll_t ngt_rint_poll; static th_close_t ngt_close; @@ -117,7 +119,8 @@ static struct ttyhook ngt_hook = { .th_getc_inject = ngt_getc_inject, .th_getc_poll = ngt_getc_poll, - .th_rint_bypass = ngt_rint_bypass, + .th_rint = ngt_rint, + .th_rint_bypass = ngt_rint_bypass, .th_rint_poll = ngt_rint_poll, .th_close = ngt_close, }; @@ -401,6 +404,12 @@ return (sc->outqlen); } +/* + * Optimised TTY input. + * + * We get a buffer pointer to hopefully a complete data frame. Do not check for + * the hotchar, just pass it on. + */ static size_t ngt_rint_bypass(struct tty *tp, const void *buf, size_t len) { @@ -410,6 +419,8 @@ size_t total = 0; int error = 0, length; + tty_lock_assert(tp, MA_OWNED); + if (sc->hook == NULL) return (0); @@ -430,11 +441,75 @@ total += length; m->m_pkthdr.len += length; } + if (sc->m != NULL) { + /* + * Odd, we have changed from non-bypass to bypass. It is + * unlikely but not impossible, flush the data first. + */ + sc->m->m_data = sc->m->m_pktdat; + NG_SEND_DATA_ONLY(error, sc->hook, sc->m); + sc->m = NULL; + } NG_SEND_DATA_ONLY(error, sc->hook, m); return (total); } +/* + * Receive data coming from the device one char at a time, when it is not in + * bypass mode. + */ +static int +ngt_rint(struct tty *tp, char c, int flags) +{ + sc_p sc = ttyhook_softc(tp); + node_p node = sc->node; + struct mbuf *m; + int error = 0; + + tty_lock_assert(tp, MA_OWNED); + + if (sc->hook == NULL) + return (0); + + if (flags != 0) { + /* framing error or overrun on this char */ + if (sc->flags & FLG_DEBUG) + log(LOG_DEBUG, "%s: line error %x\n", + NG_NODE_NAME(node), flags); + return (0); + } + + /* Get a new header mbuf if we need one */ + if (!(m = sc->m)) { + MGETHDR(m, M_DONTWAIT, MT_DATA); + if (!m) { + if (sc->flags & FLG_DEBUG) + log(LOG_ERR, + "%s: can't get mbuf\n", NG_NODE_NAME(node)); + return (ENOBUFS); + } + m->m_len = m->m_pkthdr.len = 0; + m->m_pkthdr.rcvif = NULL; + sc->m = m; + } + + /* Add char to mbuf */ + *mtod(m, u_char *) = c; + m->m_data++; + m->m_len++; + m->m_pkthdr.len++; + + /* Ship off mbuf if it's time */ + if (sc->hotchar == -1 || c == sc->hotchar || m->m_len >= MHLEN) { + m->m_data = m->m_pktdat; + sc->m = NULL; + NG_SEND_DATA_ONLY(error, sc->hook, m); /* Will queue */ + } + + return (error); +} + static size_t ngt_rint_poll(struct tty *tp) {