summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-09-24 08:26:03 +0000
committerphk <phk@FreeBSD.org>2004-09-24 08:26:03 +0000
commit6ee26d135f9f0031511789d70decdebbefaf1146 (patch)
tree468bd97a15cb8dfdaaf864bf50fa5e865588e261 /sys
parent5dd2cd84fe935437286d31918a2e395dd887d352 (diff)
downloadFreeBSD-src-6ee26d135f9f0031511789d70decdebbefaf1146.zip
FreeBSD-src-6ee26d135f9f0031511789d70decdebbefaf1146.tar.gz
Hold threadcount while throbbing cdevsw in our underlying driver.
This is a bit heavyhanded, and will be simplified once the tty code learns to properly deal with disappearing hw and drivers.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/tty.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index b2b4d36..dfa9490 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -227,6 +227,23 @@ static int drainwait = 5*60;
SYSCTL_INT(_kern, OID_AUTO, drainwait, CTLFLAG_RW, &drainwait,
0, "Output drain timeout in seconds");
+static struct tty *
+tty_gettp(struct cdev *dev)
+{
+ struct tty *tp;
+ struct cdevsw *csw;
+
+ csw = dev_refthread(dev);
+ KASSERT(csw != NULL, ("No cdevsw in ttycode (%s)", devtoname(dev)));
+ KASSERT(csw->d_flags & D_TTY,
+ ("non D_TTY (%s) in tty code", devtoname(dev)));
+ dev_relthread(dev);
+ tp = dev->si_tty;
+ KASSERT(tp != NULL,
+ ("no tty pointer on (%s) in tty code", devtoname(dev)));
+ return (tp);
+}
+
/*
* Initial open of tty, or (re)entry to standard tty line discipline.
*/
@@ -1225,11 +1242,8 @@ ttypoll(struct cdev *dev, int events, struct thread *td)
int revents = 0;
struct tty *tp;
- KASSERT(devsw(dev)->d_flags & D_TTY,
- ("ttypoll() called on non D_TTY device (%s)", devtoname(dev)));
- tp = dev->si_tty;
- KASSERT(tp != NULL,
- ("ttypoll(): no tty pointer on device (%s)", devtoname(dev)));
+ tp = tty_gettp(dev);
+
if (tp == NULL) /* XXX used to return ENXIO, but that means true! */
return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM))
| POLLHUP);
@@ -1265,11 +1279,8 @@ ttykqfilter(struct cdev *dev, struct knote *kn)
struct knlist *klist;
int s;
- KASSERT(devsw(dev)->d_flags & D_TTY,
- ("ttykqfilter() called on non D_TTY device (%s)", devtoname(dev)));
- tp = dev->si_tty;
- KASSERT(tp != NULL,
- ("ttykqfilter(): no tty pointer on device (%s)", devtoname(dev)));
+ tp = tty_gettp(dev);
+
switch (kn->kn_filter) {
case EVFILT_READ:
klist = &tp->t_rsel.si_note;
@@ -2994,11 +3005,8 @@ ttyread(struct cdev *dev, struct uio *uio, int flag)
{
struct tty *tp;
- KASSERT(devsw(dev)->d_flags & D_TTY,
- ("ttyread() called on non D_TTY device (%s)", devtoname(dev)));
- tp = dev->si_tty;
- KASSERT(tp != NULL,
- ("ttyread(): no tty pointer on device (%s)", devtoname(dev)));
+ tp = tty_gettp(dev);
+
if (tp->t_state & TS_GONE)
return (ENODEV);
return (ttyld_read(tp, uio, flag));
@@ -3009,11 +3017,8 @@ ttywrite(struct cdev *dev, struct uio *uio, int flag)
{
struct tty *tp;
- KASSERT(devsw(dev)->d_flags & D_TTY,
- ("ttywrite() called on non D_TTY device (%s)", devtoname(dev)));
- tp = dev->si_tty;
- KASSERT(tp != NULL,
- ("ttywrite(): no tty pointer on device (%s)", devtoname(dev)));
+ tp = tty_gettp(dev);
+
if (tp->t_state & TS_GONE)
return (ENODEV);
return (ttyld_write(tp, uio, flag));
OpenPOWER on IntegriCloud