Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jan 2016 22:48:05 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r294959 - in stable/10/sys: dev/uart kern sys
Message-ID:  <201601272248.u0RMm5Ia025186@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Wed Jan 27 22:48:04 2016
New Revision: 294959
URL: https://svnweb.freebsd.org/changeset/base/294959

Log:
  MFC: r294362, r294414, r294753
  
  - Fix tty_drain() and, thus, TIOCDRAIN of the current tty(4) incarnation
    to actually wait until the TX FIFOs of UARTs have be drained before
    returning. This is done by bringing the equivalent of the TS_BUSY flag
    found in the previous implementation back in an ABI-preserving way.
    Reported and tested by: Patrick Powell
  - Make the code consistent with itself style-wise and bring it closer
    to style(9).
  - Mark unused arguments as such.
  - Make the ttystates table const.

Modified:
  stable/10/sys/dev/uart/uart_tty.c
  stable/10/sys/kern/tty.c
  stable/10/sys/sys/ttydevsw.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/uart/uart_tty.c
==============================================================================
--- stable/10/sys/dev/uart/uart_tty.c	Wed Jan 27 22:31:08 2016	(r294958)
+++ stable/10/sys/dev/uart/uart_tty.c	Wed Jan 27 22:48:04 2016	(r294959)
@@ -57,6 +57,16 @@ static cn_putc_t uart_cnputc;
 static cn_grab_t uart_cngrab;
 static cn_ungrab_t uart_cnungrab;
 
+static tsw_open_t uart_tty_open;
+static tsw_close_t uart_tty_close;
+static tsw_outwakeup_t uart_tty_outwakeup;
+static tsw_inwakeup_t uart_tty_inwakeup;
+static tsw_ioctl_t uart_tty_ioctl;
+static tsw_param_t uart_tty_param;
+static tsw_modem_t uart_tty_modem;
+static tsw_free_t uart_tty_free;
+static tsw_busy_t uart_tty_busy;
+
 CONSOLE_DRIVER(uart);
 
 static struct uart_devinfo uart_console;
@@ -157,7 +167,7 @@ uart_tty_close(struct tty *tp)
 	struct uart_softc *sc;
 
 	sc = tty_softc(tp);
-	if (sc == NULL || sc->sc_leaving || !sc->sc_opened) 
+	if (sc == NULL || sc->sc_leaving || !sc->sc_opened)
 		return;
 
 	if (sc->sc_hwiflow)
@@ -169,7 +179,6 @@ uart_tty_close(struct tty *tp)
 
 	wakeup(sc);
 	sc->sc_opened = 0;
-	return;
 }
 
 static void
@@ -215,7 +224,8 @@ uart_tty_inwakeup(struct tty *tp)
 }
 
 static int
-uart_tty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
+uart_tty_ioctl(struct tty *tp, u_long cmd, caddr_t data,
+    struct thread *td __unused)
 {
 	struct uart_softc *sc;
 
@@ -262,8 +272,8 @@ uart_tty_param(struct tty *tp, struct te
 	}
 	stopbits = (t->c_cflag & CSTOPB) ? 2 : 1;
 	if (t->c_cflag & PARENB)
-		parity = (t->c_cflag & PARODD) ? UART_PARITY_ODD
-		    : UART_PARITY_EVEN;
+		parity = (t->c_cflag & PARODD) ? UART_PARITY_ODD :
+		    UART_PARITY_EVEN;
 	else
 		parity = UART_PARITY_NONE;
 	if (UART_PARAM(sc, t->c_ospeed, databits, stopbits, parity) != 0)
@@ -291,7 +301,7 @@ uart_tty_modem(struct tty *tp, int biton
 
 	sc = tty_softc(tp);
 	if (biton != 0 || bitoff != 0)
-		UART_SETSIG(sc, SER_DELTA(bitoff|biton) | biton);
+		UART_SETSIG(sc, SER_DELTA(bitoff | biton) | biton);
 	return (sc->sc_hwsig);
 }
 
@@ -350,7 +360,7 @@ uart_tty_intr(void *arg)
 }
 
 static void
-uart_tty_free(void *arg)
+uart_tty_free(void *arg __unused)
 {
 
 	/*
@@ -361,6 +371,18 @@ uart_tty_free(void *arg)
 	 */
 }
 
+static bool
+uart_tty_busy(struct tty *tp)
+{
+	struct uart_softc *sc;
+
+	sc = tty_softc(tp);
+	if (sc == NULL || sc->sc_leaving)
+                return (FALSE);
+
+	return (sc->sc_txbusy);
+}
+
 static struct ttydevsw uart_tty_class = {
 	.tsw_flags	= TF_INITLOCK|TF_CALLOUT,
 	.tsw_open	= uart_tty_open,
@@ -371,6 +393,7 @@ static struct ttydevsw uart_tty_class = 
 	.tsw_param	= uart_tty_param,
 	.tsw_modem	= uart_tty_modem,
 	.tsw_free	= uart_tty_free,
+	.tsw_busy	= uart_tty_busy,
 };
 
 int

Modified: stable/10/sys/kern/tty.c
==============================================================================
--- stable/10/sys/kern/tty.c	Wed Jan 27 22:31:08 2016	(r294958)
+++ stable/10/sys/kern/tty.c	Wed Jan 27 22:48:04 2016	(r294959)
@@ -132,11 +132,11 @@ tty_drain(struct tty *tp, int leaving)
 		/* buffer is inaccessible */
 		return (0);
 
-	while (ttyoutq_bytesused(&tp->t_outq) > 0) {
+	while (ttyoutq_bytesused(&tp->t_outq) > 0 || ttydevsw_busy(tp)) {
 		ttydevsw_outwakeup(tp);
 		/* Could be handled synchronously. */
 		bytesused = ttyoutq_bytesused(&tp->t_outq);
-		if (bytesused == 0)
+		if (bytesused == 0 && !ttydevsw_busy(tp))
 			return (0);
 
 		/* Wait for data to be drained. */
@@ -175,6 +175,7 @@ tty_drain(struct tty *tp, int leaving)
 static __inline int
 ttydev_enter(struct tty *tp)
 {
+
 	tty_lock(tp);
 
 	if (tty_gone(tp) || !tty_opened(tp)) {
@@ -189,6 +190,7 @@ ttydev_enter(struct tty *tp)
 static void
 ttydev_leave(struct tty *tp)
 {
+
 	tty_lock_assert(tp, MA_OWNED);
 
 	if (tty_opened(tp) || tp->t_flags & TF_OPENCLOSE) {
@@ -234,7 +236,8 @@ ttydev_leave(struct tty *tp)
  * Operations that are exposed through the character device in /dev.
  */
 static int
-ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
+ttydev_open(struct cdev *dev, int oflags, int devtype __unused,
+    struct thread *td)
 {
 	struct tty *tp;
 	int error = 0;
@@ -332,7 +335,8 @@ done:	tp->t_flags &= ~TF_OPENCLOSE;
 }
 
 static int
-ttydev_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
+ttydev_close(struct cdev *dev, int fflag, int devtype __unused,
+    struct thread *td __unused)
 {
 	struct tty *tp = dev->si_drv1;
 
@@ -373,6 +377,7 @@ ttydev_close(struct cdev *dev, int fflag
 static __inline int
 tty_is_ctty(struct tty *tp, struct proc *p)
 {
+
 	tty_lock_assert(tp, MA_OWNED);
 
 	return (p->p_session == tp->t_session && p->p_flag & P_CONTROLT);
@@ -653,7 +658,7 @@ tty_kqops_read_detach(struct knote *kn)
 }
 
 static int
-tty_kqops_read_event(struct knote *kn, long hint)
+tty_kqops_read_event(struct knote *kn, long hint __unused)
 {
 	struct tty *tp = kn->kn_hook;
 
@@ -677,7 +682,7 @@ tty_kqops_write_detach(struct knote *kn)
 }
 
 static int
-tty_kqops_write_event(struct knote *kn, long hint)
+tty_kqops_write_event(struct knote *kn, long hint __unused)
 {
 	struct tty *tp = kn->kn_hook;
 
@@ -697,6 +702,7 @@ static struct filterops tty_kqops_read =
 	.f_detach = tty_kqops_read_detach,
 	.f_event = tty_kqops_read_event,
 };
+
 static struct filterops tty_kqops_write = {
 	.f_isfd = 1,
 	.f_detach = tty_kqops_write_detach,
@@ -752,7 +758,8 @@ static struct cdevsw ttydev_cdevsw = {
  */
 
 static int
-ttyil_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
+ttyil_open(struct cdev *dev, int oflags __unused, int devtype __unused,
+    struct thread *td)
 {
 	struct tty *tp;
 	int error = 0;
@@ -771,14 +778,18 @@ ttyil_open(struct cdev *dev, int oflags,
 }
 
 static int
-ttyil_close(struct cdev *dev, int flag, int mode, struct thread *td)
+ttyil_close(struct cdev *dev __unused, int flag __unused, int mode __unused,
+    struct thread *td __unused)
 {
+
 	return (0);
 }
 
 static int
-ttyil_rdwr(struct cdev *dev, struct uio *uio, int ioflag)
+ttyil_rdwr(struct cdev *dev __unused, struct uio *uio __unused,
+    int ioflag __unused)
 {
+
 	return (ENODEV);
 }
 
@@ -875,45 +886,49 @@ tty_init_console(struct tty *tp, speed_t
  */
 
 static int
-ttydevsw_defopen(struct tty *tp)
+ttydevsw_defopen(struct tty *tp __unused)
 {
 
 	return (0);
 }
 
 static void
-ttydevsw_defclose(struct tty *tp)
+ttydevsw_defclose(struct tty *tp __unused)
 {
+
 }
 
 static void
-ttydevsw_defoutwakeup(struct tty *tp)
+ttydevsw_defoutwakeup(struct tty *tp __unused)
 {
 
 	panic("Terminal device has output, while not implemented");
 }
 
 static void
-ttydevsw_definwakeup(struct tty *tp)
+ttydevsw_definwakeup(struct tty *tp __unused)
 {
+
 }
 
 static int
-ttydevsw_defioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
+ttydevsw_defioctl(struct tty *tp __unused, u_long cmd __unused,
+    caddr_t data __unused, struct thread *td __unused)
 {
 
 	return (ENOIOCTL);
 }
 
 static int
-ttydevsw_defcioctl(struct tty *tp, int unit, u_long cmd, caddr_t data, struct thread *td)
+ttydevsw_defcioctl(struct tty *tp __unused, int unit __unused,
+    u_long cmd __unused, caddr_t data __unused, struct thread *td __unused)
 {
 
 	return (ENOIOCTL);
 }
 
 static int
-ttydevsw_defparam(struct tty *tp, struct termios *t)
+ttydevsw_defparam(struct tty *tp __unused, struct termios *t)
 {
 
 	/*
@@ -935,7 +950,8 @@ ttydevsw_defparam(struct tty *tp, struct
 }
 
 static int
-ttydevsw_defmodem(struct tty *tp, int sigon, int sigoff)
+ttydevsw_defmodem(struct tty *tp __unused, int sigon __unused,
+    int sigoff __unused)
 {
 
 	/* Simulate a carrier to make the TTY layer happy. */
@@ -943,25 +959,34 @@ ttydevsw_defmodem(struct tty *tp, int si
 }
 
 static int
-ttydevsw_defmmap(struct tty *tp, vm_ooffset_t offset, vm_paddr_t *paddr,
-    int nprot, vm_memattr_t *memattr)
+ttydevsw_defmmap(struct tty *tp __unused, vm_ooffset_t offset __unused,
+    vm_paddr_t *paddr __unused, int nprot __unused,
+    vm_memattr_t *memattr __unused)
 {
 
 	return (-1);
 }
 
 static void
-ttydevsw_defpktnotify(struct tty *tp, char event)
+ttydevsw_defpktnotify(struct tty *tp __unused, char event __unused)
 {
+
 }
 
 static void
-ttydevsw_deffree(void *softc)
+ttydevsw_deffree(void *softc __unused)
 {
 
 	panic("Terminal device freed without a free-handler");
 }
 
+static bool
+ttydevsw_defbusy(struct tty *tp __unused)
+{
+
+	return (FALSE);
+}
+
 /*
  * TTY allocation and deallocation. TTY devices can be deallocated when
  * the driver doesn't use it anymore, when the TTY isn't a session's
@@ -996,6 +1021,7 @@ tty_alloc_mutex(struct ttydevsw *tsw, vo
 	PATCH_FUNC(mmap);
 	PATCH_FUNC(pktnotify);
 	PATCH_FUNC(free);
+	PATCH_FUNC(busy);
 #undef PATCH_FUNC
 
 	tp = malloc(sizeof(struct tty), M_TTY, M_WAITOK|M_ZERO);
@@ -1082,6 +1108,7 @@ tty_rel_free(struct tty *tp)
 void
 tty_rel_pgrp(struct tty *tp, struct pgrp *pg)
 {
+
 	MPASS(tp->t_sessioncnt > 0);
 	tty_lock_assert(tp, MA_OWNED);
 
@@ -1094,6 +1121,7 @@ tty_rel_pgrp(struct tty *tp, struct pgrp
 void
 tty_rel_sess(struct tty *tp, struct session *sess)
 {
+
 	MPASS(tp->t_sessioncnt > 0);
 
 	/* Current session has left. */
@@ -1108,6 +1136,7 @@ tty_rel_sess(struct tty *tp, struct sess
 void
 tty_rel_gone(struct tty *tp)
 {
+
 	MPASS(!tty_gone(tp));
 
 	/* Simulate carrier removal. */
@@ -1129,6 +1158,7 @@ tty_rel_gone(struct tty *tp)
 static void
 tty_to_xtty(struct tty *tp, struct xtty *xt)
 {
+
 	tty_lock_assert(tp, MA_OWNED);
 
 	xt->xt_size = sizeof(struct xtty);
@@ -1380,6 +1410,7 @@ tty_signal_pgrp(struct tty *tp, int sig)
 void
 tty_wakeup(struct tty *tp, int flags)
 {
+
 	if (tp->t_flags & TF_ASYNC && tp->t_sigio != NULL)
 		pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
 
@@ -1442,6 +1473,7 @@ tty_timedwait(struct tty *tp, struct cv 
 void
 tty_flush(struct tty *tp, int flags)
 {
+
 	if (flags & FWRITE) {
 		tp->t_flags &= ~TF_HIWAT_OUT;
 		ttyoutq_flush(&tp->t_outq);
@@ -1832,10 +1864,11 @@ tty_ioctl(struct tty *tp, u_long cmd, vo
 dev_t
 tty_udev(struct tty *tp)
 {
+
 	if (tp->t_dev)
-		return dev2udev(tp->t_dev);
+		return (dev2udev(tp->t_dev));
 	else
-		return NODEV;
+		return (NODEV);
 }
 
 int
@@ -1904,8 +1937,8 @@ ttyhook_defrint(struct tty *tp, char c, 
 }
 
 int
-ttyhook_register(struct tty **rtp, struct proc *p, int fd,
-    struct ttyhook *th, void *softc)
+ttyhook_register(struct tty **rtp, struct proc *p, int fd, struct ttyhook *th,
+    void *softc)
 {
 	struct tty *tp;
 	struct file *fp;
@@ -2056,7 +2089,7 @@ static struct cdevsw ttyconsdev_cdevsw =
 };
 
 static void
-ttyconsdev_init(void *unused)
+ttyconsdev_init(void *unused __unused)
 {
 
 	dev_console = make_dev_credf(MAKEDEV_ETERNAL, &ttyconsdev_cdevsw, 0,
@@ -2081,7 +2114,7 @@ ttyconsdev_select(const char *name)
 #include <ddb/ddb.h>
 #include <ddb/db_sym.h>
 
-static struct {
+static const struct {
 	int flag;
 	char val;
 } ttystates[] = {
@@ -2134,6 +2167,7 @@ static struct {
 static void
 _db_show_devsw(const char *sep, const struct ttydevsw *tsw)
 {
+
 	db_printf("%sdevsw: ", sep);
 	db_printsym((db_addr_t)tsw, DB_STGY_ANY);
 	db_printf(" (%p)\n", tsw);
@@ -2148,9 +2182,11 @@ _db_show_devsw(const char *sep, const st
 	DB_PRINTSYM(pktnotify, tsw->tsw_pktnotify);
 	DB_PRINTSYM(free, tsw->tsw_free);
 }
+
 static void
 _db_show_hooks(const char *sep, const struct ttyhook *th)
 {
+
 	db_printf("%shook: ", sep);
 	db_printsym((db_addr_t)th, DB_STGY_ANY);
 	db_printf(" (%p)\n", th);
@@ -2256,17 +2292,13 @@ DB_SHOW_ALL_COMMAND(ttys, db_show_all_tt
 		isiz = tp->t_inq.ti_nblocks * TTYINQ_DATASIZE;
 		osiz = tp->t_outq.to_nblocks * TTYOUTQ_DATASIZE;
 
-		db_printf("%p %10s %5zu %4u %4u %4zu %5zu %4u %4zu %5u %5d %5d ",
-		    tp,
-		    tty_devname(tp),
-		    isiz,
+		db_printf("%p %10s %5zu %4u %4u %4zu %5zu %4u %4zu %5u %5d "
+		    "%5d ", tp, tty_devname(tp), isiz,
 		    tp->t_inq.ti_linestart - tp->t_inq.ti_begin,
 		    tp->t_inq.ti_end - tp->t_inq.ti_linestart,
-		    isiz - tp->t_inlow,
-		    osiz,
+		    isiz - tp->t_inlow, osiz,
 		    tp->t_outq.to_end - tp->t_outq.to_begin,
-		    osiz - tp->t_outlow,
-		    MIN(tp->t_column, 99999),
+		    osiz - tp->t_outlow, MIN(tp->t_column, 99999),
 		    tp->t_session ? tp->t_session->s_sid : 0,
 		    tp->t_pgrp ? tp->t_pgrp->pg_id : 0);
 

Modified: stable/10/sys/sys/ttydevsw.h
==============================================================================
--- stable/10/sys/sys/ttydevsw.h	Wed Jan 27 22:31:08 2016	(r294958)
+++ stable/10/sys/sys/ttydevsw.h	Wed Jan 27 22:48:04 2016	(r294959)
@@ -54,6 +54,7 @@ typedef int tsw_mmap_t(struct tty *tp, v
     vm_paddr_t * paddr, int nprot, vm_memattr_t *memattr);
 typedef void tsw_pktnotify_t(struct tty *tp, char event);
 typedef void tsw_free_t(void *softc);
+typedef bool tsw_busy_t(struct tty *tp);
 
 struct ttydevsw {
 	unsigned int	tsw_flags;	/* Default TTY flags. */
@@ -74,21 +75,25 @@ struct ttydevsw {
 
 	tsw_free_t	*tsw_free;	/* Destructor. */
 
-	void		*tsw_spare[4];	/* For future use. */
+	tsw_busy_t	*tsw_busy;	/* Draining output. */
+
+	void		*tsw_spare[3];	/* For future use. */
 };
 
 static __inline int
 ttydevsw_open(struct tty *tp)
 {
+
 	tty_lock_assert(tp, MA_OWNED);
 	MPASS(!tty_gone(tp));
 
-	return tp->t_devsw->tsw_open(tp);
+	return (tp->t_devsw->tsw_open(tp));
 }
 
 static __inline void
 ttydevsw_close(struct tty *tp)
 {
+
 	tty_lock_assert(tp, MA_OWNED);
 	MPASS(!tty_gone(tp));
 
@@ -98,6 +103,7 @@ ttydevsw_close(struct tty *tp)
 static __inline void
 ttydevsw_outwakeup(struct tty *tp)
 {
+
 	tty_lock_assert(tp, MA_OWNED);
 	MPASS(!tty_gone(tp));
 
@@ -111,6 +117,7 @@ ttydevsw_outwakeup(struct tty *tp)
 static __inline void
 ttydevsw_inwakeup(struct tty *tp)
 {
+
 	tty_lock_assert(tp, MA_OWNED);
 	MPASS(!tty_gone(tp));
 
@@ -124,49 +131,56 @@ ttydevsw_inwakeup(struct tty *tp)
 static __inline int
 ttydevsw_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
 {
+
 	tty_lock_assert(tp, MA_OWNED);
 	MPASS(!tty_gone(tp));
 
-	return tp->t_devsw->tsw_ioctl(tp, cmd, data, td);
+	return (tp->t_devsw->tsw_ioctl(tp, cmd, data, td));
 }
 
 static __inline int
-ttydevsw_cioctl(struct tty *tp, int unit, u_long cmd, caddr_t data, struct thread *td)
+ttydevsw_cioctl(struct tty *tp, int unit, u_long cmd, caddr_t data,
+    struct thread *td)
 {
+
 	tty_lock_assert(tp, MA_OWNED);
 	MPASS(!tty_gone(tp));
 
-	return tp->t_devsw->tsw_cioctl(tp, unit, cmd, data, td);
+	return (tp->t_devsw->tsw_cioctl(tp, unit, cmd, data, td));
 }
 
 static __inline int
 ttydevsw_param(struct tty *tp, struct termios *t)
 {
+
 	MPASS(!tty_gone(tp));
 
-	return tp->t_devsw->tsw_param(tp, t);
+	return (tp->t_devsw->tsw_param(tp, t));
 }
 
 static __inline int
 ttydevsw_modem(struct tty *tp, int sigon, int sigoff)
 {
+
 	MPASS(!tty_gone(tp));
 
-	return tp->t_devsw->tsw_modem(tp, sigon, sigoff);
+	return (tp->t_devsw->tsw_modem(tp, sigon, sigoff));
 }
 
 static __inline int
 ttydevsw_mmap(struct tty *tp, vm_ooffset_t offset, vm_paddr_t *paddr,
     int nprot, vm_memattr_t *memattr)
 {
+
 	MPASS(!tty_gone(tp));
 
-	return tp->t_devsw->tsw_mmap(tp, offset, paddr, nprot, memattr);
+	return (tp->t_devsw->tsw_mmap(tp, offset, paddr, nprot, memattr));
 }
 
 static __inline void
 ttydevsw_pktnotify(struct tty *tp, char event)
 {
+
 	tty_lock_assert(tp, MA_OWNED);
 	MPASS(!tty_gone(tp));
 
@@ -176,9 +190,20 @@ ttydevsw_pktnotify(struct tty *tp, char 
 static __inline void
 ttydevsw_free(struct tty *tp)
 {
+
 	MPASS(tty_gone(tp));
 
 	tp->t_devsw->tsw_free(tty_softc(tp));
 }
 
+static __inline bool
+ttydevsw_busy(struct tty *tp)
+{
+
+	tty_lock_assert(tp, MA_OWNED);
+	MPASS(!tty_gone(tp));
+
+	return (tp->t_devsw->tsw_busy(tp));
+}
+
 #endif /* !_SYS_TTYDEVSW_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601272248.u0RMm5Ia025186>