summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-09-30 10:38:48 +0000
committerphk <phk@FreeBSD.org>2004-09-30 10:38:48 +0000
commit9743317a02fc6556a3881733cf4fcfdc18601027 (patch)
tree5ceb1ce4303492416e395c2747124cf01cdc0393
parent187850e01e16ed2db1e50b14d1d9f6e50efb61a8 (diff)
downloadFreeBSD-src-9743317a02fc6556a3881733cf4fcfdc18601027.zip
FreeBSD-src-9743317a02fc6556a3881733cf4fcfdc18601027.tar.gz
Assign a global unit number for the tty slave devices (init/lock) using
the new subr_unit.c code. For now assert Giant in ttycreate() and ttyfree(). It is not obvious that it will ever pay off to lock these with anything else.
-rw-r--r--sys/kern/tty.c29
-rw-r--r--sys/sys/tty.h1
2 files changed, 24 insertions, 6 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 191d45a..bcb3f9e 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -254,6 +254,8 @@ static u_char const char_type[] = {
static TAILQ_HEAD(, tty) tty_list = TAILQ_HEAD_INITIALIZER(tty_list);
static struct mtx tty_list_mutex;
+static struct unrhdr *tty_unit;
+
static int drainwait = 5*60;
SYSCTL_INT(_kern, OID_AUTO, drainwait, CTLFLAG_RW, &drainwait,
0, "Output drain timeout in seconds");
@@ -2893,16 +2895,27 @@ ttycreate(struct tty *tp, struct cdevsw *csw, int unit, int flags, const char *f
char namebuf[SPECNAMELEN - 3]; /* XXX space for "tty" */
va_list ap;
struct cdev *cp;
- int i, minor;
+ int i, minor, sminor, sunit;
+
+ mtx_assert(&Giant, MA_OWNED);
+
+ if (tty_unit == NULL)
+ tty_unit = new_unrhdr(0, 0xffff);
- if (csw == NULL)
+ sunit = alloc_unr(tty_unit);
+ tp->t_devunit = sunit;
+
+ if (csw == NULL) {
csw = &tty_cdevsw;
+ unit = sunit;
+ }
KASSERT(csw->d_purge == NULL || csw->d_purge == ttypurge,
("tty should not have d_purge"));
csw->d_purge = ttypurge;
minor = unit2minor(unit);
+ sminor = unit2minor(sunit);
va_start(ap, fmt);
i = vsnrprintf(namebuf, sizeof namebuf, 32, fmt, ap);
va_end(ap);
@@ -2915,14 +2928,14 @@ ttycreate(struct tty *tp, struct cdevsw *csw, int unit, int flags, const char *f
cp->si_tty = tp;
cp->si_drv1 = tp->t_sc;
- cp = make_dev(&ttys_cdevsw, minor | MINOR_INIT,
+ cp = make_dev(&ttys_cdevsw, sminor | MINOR_INIT,
UID_ROOT, GID_WHEEL, 0600, "tty%s.init", namebuf);
dev_depends(tp->t_dev, cp);
cp->si_drv1 = tp->t_sc;
cp->si_drv2 = &tp->t_init_in;
cp->si_tty = tp;
- cp = make_dev(&ttys_cdevsw, minor | MINOR_LOCK,
+ cp = make_dev(&ttys_cdevsw, sminor | MINOR_LOCK,
UID_ROOT, GID_WHEEL, 0600, "tty%s.lock", namebuf);
dev_depends(tp->t_dev, cp);
cp->si_drv1 = tp->t_sc;
@@ -2936,14 +2949,14 @@ ttycreate(struct tty *tp, struct cdevsw *csw, int unit, int flags, const char *f
cp->si_drv1 = tp->t_sc;
cp->si_tty = tp;
- cp = make_dev(&ttys_cdevsw, minor | MINOR_CALLOUT | MINOR_INIT,
+ cp = make_dev(&ttys_cdevsw, sminor | MINOR_CALLOUT | MINOR_INIT,
UID_UUCP, GID_DIALER, 0660, "cua%s.init", namebuf);
dev_depends(tp->t_dev, cp);
cp->si_drv1 = tp->t_sc;
cp->si_drv2 = &tp->t_init_out;
cp->si_tty = tp;
- cp = make_dev(&ttys_cdevsw, minor | MINOR_CALLOUT | MINOR_LOCK,
+ cp = make_dev(&ttys_cdevsw, sminor | MINOR_CALLOUT | MINOR_LOCK,
UID_UUCP, GID_DIALER, 0660, "cua%s.lock", namebuf);
dev_depends(tp->t_dev, cp);
cp->si_drv1 = tp->t_sc;
@@ -2983,9 +2996,13 @@ ttygone(struct tty *tp)
void
ttyfree(struct tty *tp)
{
+ u_int unit;
+ mtx_assert(&Giant, MA_OWNED);
ttygone(tp);
+ unit = tp->t_devunit;
destroy_dev(tp->t_mdev);
+ free_unr(tty_unit, unit);
}
static int
diff --git a/sys/sys/tty.h b/sys/sys/tty.h
index 0054a42..75d183b 100644
--- a/sys/sys/tty.h
+++ b/sys/sys/tty.h
@@ -102,6 +102,7 @@ struct tty {
int t_line; /* Interface to device drivers. */
struct cdev *t_dev; /* Device. */
struct cdev *t_mdev; /* Device. */
+ u_int t_devunit; /* Cdev unit number */
int t_state; /* Device and driver (TS*) state. */
int t_flags; /* Tty flags. */
int t_timeout; /* Timeout for ttywait() */
OpenPOWER on IntegriCloud