From owner-svn-src-head@FreeBSD.ORG Mon Nov 5 17:50:41 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 603968A3; Mon, 5 Nov 2012 17:50:41 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 446A08FC12; Mon, 5 Nov 2012 17:50:41 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qA5HofO3049835; Mon, 5 Nov 2012 17:50:41 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qA5Hof8U049831; Mon, 5 Nov 2012 17:50:41 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201211051750.qA5Hof8U049831@svn.freebsd.org> From: Hans Petter Selasky Date: Mon, 5 Nov 2012 17:50:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r242619 - in head/sys: dev/usb/serial sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 05 Nov 2012 17:50:41 -0000 Author: hselasky Date: Mon Nov 5 17:50:40 2012 New Revision: 242619 URL: http://svnweb.freebsd.org/changeset/base/242619 Log: Add a jitter buffer in the common USB serial driver code which temporarily stores characters if the TTY buffer is full when used a as a console. This can happen when a console is suspended. Also properly do the flow stop signalling when this happens and flow start when the condition changes back to normal again. Bump __FreeBSD_version to force external kernel modules to be recompiled. No kernel API changes. MFC after: 1 week Suggested by: ed @ Modified: head/sys/dev/usb/serial/usb_serial.c head/sys/dev/usb/serial/usb_serial.h head/sys/sys/param.h Modified: head/sys/dev/usb/serial/usb_serial.c ============================================================================== --- head/sys/dev/usb/serial/usb_serial.c Mon Nov 5 17:42:50 2012 (r242618) +++ head/sys/dev/usb/serial/usb_serial.c Mon Nov 5 17:50:40 2012 (r242619) @@ -162,6 +162,7 @@ static tsw_ioctl_t ucom_ioctl; static tsw_modem_t ucom_modem; static tsw_param_t ucom_param; static tsw_outwakeup_t ucom_outwakeup; +static tsw_inwakeup_t ucom_inwakeup; static tsw_free_t ucom_free; static struct ttydevsw ucom_class = { @@ -169,6 +170,7 @@ static struct ttydevsw ucom_class = { .tsw_open = ucom_open, .tsw_close = ucom_close, .tsw_outwakeup = ucom_outwakeup, + .tsw_inwakeup = ucom_inwakeup, .tsw_ioctl = ucom_ioctl, .tsw_param = ucom_param, .tsw_modem = ucom_modem, @@ -716,6 +718,10 @@ ucom_open(struct tty *tp) sc->sc_pls_set = 0; sc->sc_pls_clr = 0; + /* reset jitter buffer */ + sc->sc_jitterbuf_in = 0; + sc->sc_jitterbuf_out = 0; + ucom_queue_command(sc, ucom_cfg_open, NULL, &sc->sc_open_task[0].hdr, &sc->sc_open_task[1].hdr); @@ -780,6 +786,47 @@ ucom_close(struct tty *tp) } } +static void +ucom_inwakeup(struct tty *tp) +{ + struct ucom_softc *sc = tty_softc(tp); + uint16_t pos; + + if (sc == NULL) + return; + + tty_lock(tp); + + if (ttydisc_can_bypass(tp) != 0 || + (sc->sc_flag & UCOM_FLAG_HL_READY) == 0) { + tty_unlock(tp); + return; + } + + pos = sc->sc_jitterbuf_out; + + while (sc->sc_jitterbuf_in != pos) { + int c; + + c = (char)sc->sc_jitterbuf[pos]; + + if (ttydisc_rint(tp, c, 0) == -1) + break; + pos++; + if (pos >= UCOM_JITTERBUF_SIZE) + pos -= UCOM_JITTERBUF_SIZE; + } + + sc->sc_jitterbuf_out = pos; + + /* clear RTS in async fashion */ + if ((sc->sc_jitterbuf_in == pos) && + (sc->sc_flag & UCOM_FLAG_RTS_IFLOW)) + ucom_rts(sc, 0); + + tty_unlock(tp); +} + static int ucom_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) { @@ -1360,6 +1407,11 @@ ucom_put_data(struct ucom_softc *sc, str /* first check if we can pass the buffer directly */ if (ttydisc_can_bypass(tp)) { + + /* clear any jitter buffer */ + sc->sc_jitterbuf_in = 0; + sc->sc_jitterbuf_out = 0; + if (ttydisc_rint_bypass(tp, buf, cnt) != cnt) { DPRINTF("tp=%p, data lost\n", tp); } @@ -1368,8 +1420,31 @@ ucom_put_data(struct ucom_softc *sc, str /* need to loop */ for (cnt = 0; cnt != res.length; cnt++) { - if (ttydisc_rint(tp, buf[cnt], 0) == -1) { - /* XXX what should we do? */ + if (sc->sc_jitterbuf_in != sc->sc_jitterbuf_out || + ttydisc_rint(tp, buf[cnt], 0) == -1) { + uint16_t end; + uint16_t pos; + + pos = sc->sc_jitterbuf_in; + end = sc->sc_jitterbuf_out + + UCOM_JITTERBUF_SIZE - 1; + if (end >= UCOM_JITTERBUF_SIZE) + end -= UCOM_JITTERBUF_SIZE; + + for (; cnt != res.length; cnt++) { + if (pos == end) + break; + sc->sc_jitterbuf[pos] = buf[cnt]; + pos++; + if (pos >= UCOM_JITTERBUF_SIZE) + pos -= UCOM_JITTERBUF_SIZE; + } + + sc->sc_jitterbuf_in = pos; + + /* set RTS in async fashion */ + if (sc->sc_flag & UCOM_FLAG_RTS_IFLOW) + ucom_rts(sc, 1); DPRINTF("tp=%p, lost %d " "chars\n", tp, res.length - cnt); Modified: head/sys/dev/usb/serial/usb_serial.h ============================================================================== --- head/sys/dev/usb/serial/usb_serial.h Mon Nov 5 17:42:50 2012 (r242618) +++ head/sys/dev/usb/serial/usb_serial.h Mon Nov 5 17:50:40 2012 (r242619) @@ -78,6 +78,7 @@ #define UCOM_MINVER 1 #define UCOM_PREFVER UCOM_MODVER #define UCOM_MAXVER 1 +#define UCOM_JITTERBUF_SIZE 128 /* bytes */ struct usb_device; struct ucom_softc; @@ -169,6 +170,8 @@ struct ucom_softc { struct mtx *sc_mtx; void *sc_parent; int sc_subunit; + uint16_t sc_jitterbuf_in; + uint16_t sc_jitterbuf_out; uint16_t sc_portno; uint16_t sc_flag; #define UCOM_FLAG_RTS_IFLOW 0x01 /* use RTS input flow control */ @@ -191,6 +194,7 @@ struct ucom_softc { #define UCOM_LS_RTS 0x02 #define UCOM_LS_BREAK 0x04 #define UCOM_LS_RING 0x08 + uint8_t sc_jitterbuf[UCOM_JITTERBUF_SIZE]; }; #define UCOM_MTX_ASSERT(sc, what) mtx_assert((sc)->sc_mtx, what) Modified: head/sys/sys/param.h ============================================================================== --- head/sys/sys/param.h Mon Nov 5 17:42:50 2012 (r242618) +++ head/sys/sys/param.h Mon Nov 5 17:50:40 2012 (r242619) @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1000022 /* Master, propagated to newvers */ +#define __FreeBSD_version 1000023 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,