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);