Date: Thu, 28 Aug 2008 18:54:14 GMT From: Ed Schouten <ed@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 148734 for review Message-ID: <200808281854.m7SIsEwR054477@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
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));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808281854.m7SIsEwR054477>