From owner-p4-projects@FreeBSD.ORG Thu Aug 28 18:54:14 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8BEA11065675; Thu, 28 Aug 2008 18:54:14 +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 4FD95106568C for ; Thu, 28 Aug 2008 18:54:14 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 3AF368FC20 for ; Thu, 28 Aug 2008 18:54:14 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.2/8.14.2) with ESMTP id m7SIsExP054479 for ; Thu, 28 Aug 2008 18:54:14 GMT (envelope-from ed@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m7SIsEwR054477 for perforce@freebsd.org; Thu, 28 Aug 2008 18:54:14 GMT (envelope-from ed@FreeBSD.org) Date: Thu, 28 Aug 2008 18:54:14 GMT Message-Id: <200808281854.m7SIsEwR054477@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to ed@FreeBSD.org using -f From: Ed Schouten To: Perforce Change Reviews Cc: Subject: PERFORCE change 148734 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: Thu, 28 Aug 2008 18:54:14 -0000 http://perforce.freebsd.org/chv.cgi?CH=148734 Change 148734 by ed@ed_dull on 2008/08/28 18:53:25 Already add a first prototype of the packet mode code. This means we can now happily use ^S and ^Q while inside screen. Affected files ... .. //depot/projects/mpsafetty/sys/kern/tty.c#34 edit .. //depot/projects/mpsafetty/sys/kern/tty_pts.c#18 edit .. //depot/projects/mpsafetty/sys/sys/ttydevsw.h#6 edit Differences ... ==== //depot/projects/mpsafetty/sys/kern/tty.c#34 (text+ko) ==== @@ -818,7 +818,7 @@ } static void -ttydevsw_defpktnotify(struct tty *tp, int event) +ttydevsw_defpktnotify(struct tty *tp, char event) { } @@ -1382,6 +1382,17 @@ ttyinq_canonicalize(&tp->t_inq); tty_wakeup(tp, FREAD); } + + /* + * For packet mode: notify the PTY consumer that VSTOP + * and VSTART may have been changed. + */ + if (tp->t_termios.c_iflag & IXON && + tp->t_termios.c_cc[VSTOP] == CTRL('S') && + tp->t_termios.c_cc[VSTART] == CTRL('Q')) + ttydevsw_pktnotify(tp, TIOCPKT_DOSTOP); + else + ttydevsw_pktnotify(tp, TIOCPKT_NOSTOP); return (0); } case TIOCGETD: ==== //depot/projects/mpsafetty/sys/kern/tty_pts.c#18 (text+ko) ==== @@ -82,6 +82,7 @@ int pts_unit; /* (c) Device unit number. */ unsigned int pts_flags; /* (t) Device flags. */ #define PTS_PKT 0x1 /* Packet mode. */ + char pts_pkt; /* (t) Unread packet mode data. */ struct cv pts_inwait; /* (t) Blocking write() on master. */ struct selinfo pts_inpoll; /* (t) Select queue for write(). */ @@ -105,34 +106,54 @@ { struct tty *tp = fp->f_data; struct pts_softc *psc = tty_softc(tp); - int error, oresid; + int error = 0; + char pkt; if (uio->uio_resid == 0) return (0); - - /* - * Implement packet mode. When packet mode is turned on, the - * first byte contains a bitmask of events that occured (start, - * stop, flush, window size, etc). - */ + + tty_lock(tp); + + for (;;) { + /* + * Implement packet mode. When packet mode is turned on, + * the first byte contains a bitmask of events that + * occured (start, stop, flush, window size, etc). + */ + if (psc->pts_flags & PTS_PKT && psc->pts_pkt) { + pkt = psc->pts_pkt; + psc->pts_pkt = 0; + tty_unlock(tp); - if (psc->pts_flags & PTS_PKT) { - /* XXX: return proper bits. */ - error = ureadc(0, uio); - if (error != 0) + error = ureadc(pkt, uio); return (error); - if (uio->uio_resid == 0) - return (0); - } + } + + /* + * Transmit regular data. + * + * XXX: We shouldn't use ttydisc_getc_poll()! Even + * though in this implementation, there is likely going + * to be data, we should just call ttydisc_getc_uio() + * and use its return value to sleep. + */ + if (ttydisc_getc_poll(tp)) { + if (psc->pts_flags & PTS_PKT) { + /* + * XXX: Small race. Fortunately PTY + * consumers aren't multithreaded. + */ - oresid = uio->uio_resid; + tty_unlock(tp); + error = ureadc(TIOCPKT_DATA, uio); + if (error) + return (error); + tty_lock(tp); + } - tty_lock(tp); - for (;;) { - error = ttydisc_getc_uio(tp, uio); - /* We've got data (or an error). */ - if (error != 0 || uio->uio_resid != oresid) + error = ttydisc_getc_uio(tp, uio); break; + } /* Maybe the device isn't used anyway. */ if (tty_opened(tp) == 0) @@ -147,6 +168,7 @@ if (error != 0) break; } + tty_unlock(tp); return (error); @@ -367,7 +389,8 @@ if (events & (POLLIN|POLLRDNORM)) { /* See if we can getc something. */ - if (ttydisc_getc_poll(tp)) + if (ttydisc_getc_poll(tp) || + (psc->pts_flags & PTS_PKT && psc->pts_pkt)) revents |= events & (POLLIN|POLLRDNORM); } if (events & (POLLOUT|POLLWRNORM)) { @@ -486,8 +509,31 @@ } static void -ptsdrv_pktnotify(struct tty *tp, int event) +ptsdrv_pktnotify(struct tty *tp, char event) { + struct pts_softc *psc = tty_softc(tp); + + /* + * Clear conflicting flags. + */ + + switch (event) { + case TIOCPKT_STOP: + psc->pts_pkt &= ~TIOCPKT_START; + break; + case TIOCPKT_START: + psc->pts_pkt &= ~TIOCPKT_STOP; + break; + case TIOCPKT_NOSTOP: + psc->pts_pkt &= ~TIOCPKT_DOSTOP; + break; + case TIOCPKT_DOSTOP: + psc->pts_pkt &= ~TIOCPKT_NOSTOP; + break; + } + + psc->pts_pkt |= event; + ptsdrv_outwakeup(tp); } static void ==== //depot/projects/mpsafetty/sys/sys/ttydevsw.h#6 (text+ko) ==== @@ -48,7 +48,7 @@ typedef int tsw_param_t(struct tty *, struct termios *); typedef int tsw_modem_t(struct tty *, int, int); typedef int tsw_mmap_t(struct tty *, vm_offset_t, vm_paddr_t *, int); -typedef void tsw_pktnotify_t(struct tty *, int); +typedef void tsw_pktnotify_t(struct tty *, char); typedef void tsw_free_t(void *); struct ttydevsw { @@ -150,7 +150,7 @@ } static __inline void -ttydevsw_pktnotify(struct tty *tp, int event) +ttydevsw_pktnotify(struct tty *tp, char event) { tty_lock_assert(tp, MA_OWNED); MPASS(!tty_gone(tp));