Module Name:    src
Committed By:   riastradh
Date:           Mon Mar 28 12:39:29 UTC 2022

Modified Files:
        src/sys/kern: tty.c
        src/sys/sys: tty.h

Log Message:
tty(9): New ttycancel function.

This causes any current and future ttyopens to fail until ttyclose.

This is necessary for revoke to work reliably for device detach like
ucom(4) removable USB devices.  A tty driver for a removable device
needs some way to interrupt a pending .d_open so it returns promptly.
But ttyclose only interrupts ttyopen if it's already sleeping; it
won't cause a concurrent .d_open call which _will call_ but _hasn't
yet called_ ttyopen to avoid sleeping.  Using ttycancel in the tty
driver's .d_cancel makes this work.


To generate a diff of this commit:
cvs rdiff -u -r1.299 -r1.300 src/sys/kern/tty.c
cvs rdiff -u -r1.95 -r1.96 src/sys/sys/tty.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/tty.c
diff -u src/sys/kern/tty.c:1.299 src/sys/kern/tty.c:1.300
--- src/sys/kern/tty.c:1.299	Sun Dec  5 07:44:53 2021
+++ src/sys/kern/tty.c	Mon Mar 28 12:39:28 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: tty.c,v 1.299 2021/12/05 07:44:53 msaitoh Exp $	*/
+/*	$NetBSD: tty.c,v 1.300 2022/03/28 12:39:28 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.299 2021/12/05 07:44:53 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.300 2022/03/28 12:39:28 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -420,6 +420,21 @@ ttylopen(dev_t device, struct tty *tp)
 }
 
 /*
+ * Interrupt any pending I/O and make it fail.  Used before close to
+ * interrupt pending open/read/write/&c. and make it fail promptly.
+ */
+void
+ttycancel(struct tty *tp)
+{
+
+	mutex_spin_enter(&tty_lock);
+	tp->t_state |= TS_CANCEL;
+	cv_broadcast(&tp->t_outcv);
+	cv_broadcast(&tp->t_rawcv);
+	mutex_spin_exit(&tty_lock);
+}
+
+/*
  * Handle close() on a tty line: flush and set to initial state,
  * bumping generation number so that pending read/write calls
  * can detect recycling of the tty.
@@ -2750,7 +2765,9 @@ ttysleep(struct tty *tp, kcondvar_t *cv,
 	KASSERT(mutex_owned(&tty_lock));
 
 	gen = tp->t_gen;
-	if (cv == NULL)
+	if (ISSET(tp->t_state, TS_CANCEL))
+		error = ERESTART;
+	else if (cv == NULL)
 		error = kpause("ttypause", catch_p, timo, &tty_lock);
 	else if (catch_p)
 		error = cv_timedwait_sig(cv, &tty_lock, timo);

Index: src/sys/sys/tty.h
diff -u src/sys/sys/tty.h:1.95 src/sys/sys/tty.h:1.96
--- src/sys/sys/tty.h:1.95	Sun Jan 27 02:08:50 2019
+++ src/sys/sys/tty.h	Mon Mar 28 12:39:28 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: tty.h,v 1.95 2019/01/27 02:08:50 pgoyette Exp $	*/
+/*	$NetBSD: tty.h,v 1.96 2022/03/28 12:39:28 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -207,6 +207,8 @@ struct tty {
 #define	TS_KERN_ONLY	0x10000		/* Device is accessible by kernel
 					 * only, deny all userland access */
 
+#define	TS_CANCEL	0x20000		/* I/O cancelled pending close. */
+
 /* Character type information. */
 #define	ORDINARY	0
 #define	CONTROL		1
@@ -281,6 +283,7 @@ void	 ttwakeup(struct tty *);
 int	 ttwrite(struct tty *, struct uio *, int);
 void	 ttychars(struct tty *);
 int	 ttycheckoutq(struct tty *, int);
+void	 ttycancel(struct tty *);
 int	 ttyclose(struct tty *);
 void	 ttyflush(struct tty *, int);
 void	 ttygetinfo(struct tty *, int, char *, size_t);

Reply via email to