kernel - Refactor tty_token, fix SMP performance issues
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 4 Oct 2018 17:22:35 +0000 (10:22 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 4 Oct 2018 22:29:49 +0000 (15:29 -0700)
* Remove most uses of tty_token in favor of per-tty tp->t_token.
  This is particularly important for removing bottlenecks related to PTYs,
  which are used all over the place.  tty_token remains in a few places
  managing overall registration and global list manipulation.

* tty structures are now required to be persistent.  Implement a sepearate
  ttyinit() function.  Continue to allow ttyregister() and ttyunregister()
  calls, but these no longer presume destruction of the structure.

* Refactor ttymalloc() to take a **tty pointer and interlock allocations.
  Allocations are intended to be one-time.  ttymalloc() only requires the
  tty_token for initial allocations.

* Remove all critical section use that was combined with tty_token and
  tp->t_token.  Leave only the tokens.  The critical sections were
  hold-overs going all the way back to pre-SMP days.

* syscons now gets its own token, vga_token.  The ISA VGA code and
  the framebuffer code also now use this token instead of tty_token.

* The keyboard subsystem now uses kbd_token instead of tty_token.

* A few remaining serial-like devices (snp, nmdm) also get their own
  tokens, as well as use the now required tp->t_token.

* Remove use of tty_token in the session management code.  This fixes
  a niggling performance path since sessions almost universally go
  hand-in-hand with fork/exec/exit sequences.  Instead we use the
  already-existing per-hash session token.

30 files changed:
sys/bus/isa/vga_isa.c
sys/bus/u4b/serial/usb_serial.c
sys/dev/misc/atkbd/atkbd_isa.c
sys/dev/misc/atkbdc_layer/atkbdc_isa.c
sys/dev/misc/dcons/dcons_os.c
sys/dev/misc/kbd/kbd.c
sys/dev/misc/nmdm/nmdm.c
sys/dev/misc/snp/snp.c
sys/dev/misc/syscons/scvgarndr.c
sys/dev/misc/syscons/scvidctl.c
sys/dev/misc/syscons/syscons.c
sys/dev/serial/sio/sio.c
sys/dev/video/fb/bmp/splash_bmp.c
sys/dev/video/fb/fb.c
sys/dev/video/fb/fbreg.h
sys/dev/video/fb/vga.c
sys/kern/kern_proc.c
sys/kern/lwkt_token.c
sys/kern/tty.c
sys/kern/tty_cons.c
sys/kern/tty_pty.c
sys/kern/tty_subr.c
sys/net/sl/if_sl.c
sys/netgraph/tty/ng_tty.c
sys/netgraph7/bluetooth/drivers/h4/ng_h4.c
sys/netgraph7/tty/ng_tty.c
sys/platform/vkernel64/platform/console.c
sys/sys/proc.h
sys/sys/thread.h
sys/sys/tty.h

index c7d173f..da11145 100644 (file)
@@ -197,7 +197,7 @@ isavga_suspend(device_t dev)
                return (0);
        if (bootverbose)
                device_printf(dev, "saving %d bytes of video state\n", nbytes);
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        if ((*vidsw[sc->adp->va_index]->save_state)(sc->adp, sc->state_buf,
            nbytes) != 0) {
                device_printf(dev, "failed to save state (nbytes=%d)\n",
@@ -205,7 +205,7 @@ isavga_suspend(device_t dev)
                kfree(sc->state_buf, M_TEMP);
                sc->state_buf = NULL;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return (0);
 }
 
index 4331f77..2101d7a 100644 (file)
@@ -379,7 +379,8 @@ ucom_detach(struct ucom_super_softc *ssc, struct ucom_softc *sc)
        destroy_dev(sc->sc_cdev2_init);
        destroy_dev(sc->sc_cdev2_lock);
 
-       lwkt_gettoken(&tty_token);
+       if (sc->sc_tty)
+               lwkt_gettoken(&sc->sc_tty->t_token);
 
        if (ssc->sc_sysctl_ttyname != NULL) {
                sysctl_remove_oid(ssc->sc_sysctl_ttyname, 1, 0);
@@ -412,7 +413,8 @@ ucom_detach(struct ucom_super_softc *ssc, struct ucom_softc *sc)
        /* make sure we don't detach twice */
        ssc->sc_flag &= ~UCOM_FLAG_ATTACHED;
 
-       lwkt_reltoken(&tty_token);
+       if (sc->sc_tty)
+               lwkt_reltoken(&sc->sc_tty->t_token);
 }
 
 void
@@ -444,14 +446,9 @@ ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
        struct tty *tp;
        char buf[32];                   /* temporary TTY device name buffer */
 
-       lwkt_gettoken(&tty_token);
+       tp = ttymalloc(&sc->sc_tty);
 
-       sc->sc_tty = tp = ttymalloc(sc->sc_tty);
-
-       if (tp == NULL) {
-               lwkt_reltoken(&tty_token);
-               return (ENOMEM);
-       }
+       lwkt_gettoken(&tp->t_token);
 
        tp->t_sc = (void *)sc;
 
@@ -538,7 +535,8 @@ ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
                UCOM_MTX_UNLOCK(ucom_cons_softc);
        }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+
        return (0);
 }
 
@@ -564,8 +562,8 @@ ucom_detach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
        sc->sc_flag &= ~(UCOM_FLAG_HL_READY | UCOM_FLAG_LL_READY);
        UCOM_MTX_UNLOCK(sc);
 
-       lwkt_gettoken(&tty_token);
        if (tp != NULL) {
+               lwkt_gettoken(&tp->t_token);
                ucom_close_refs++;
 
                UCOM_MTX_LOCK(sc);
@@ -586,13 +584,13 @@ ucom_detach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
                        (sc->sc_callback->ucom_stop_write) (sc);
                }
                UCOM_MTX_UNLOCK(sc);
+               lwkt_reltoken(&tp->t_token);
        } else {
                DPRINTF("no tty\n");
        }
 
        dev_ops_remove_minor(&ucom_ops,ssc->sc_unit);
 
-       lwkt_reltoken(&tty_token);
        ucom_unref(ssc);
 }
 
@@ -831,10 +829,8 @@ ucom_open(struct ucom_softc *sc)
        }
        sc->sc_flag |= UCOM_FLAG_HL_READY;
 
-       lwkt_gettoken(&tty_token);
        tp = sc->sc_tty;
-
-       crit_enter();
+       lwkt_gettoken(&tp->t_token);
 
        if (!ISSET(tp->t_state, TS_ISOPEN)) {
                struct termios t;
@@ -888,23 +884,22 @@ ucom_open(struct ucom_softc *sc)
                        (*linesw[tp->t_line].l_modem)(tp, 1);
                }
        }
-       crit_exit();
 
        error = ttyopen(sc->sc_cdev, tp);
        if (error) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (error);
        }
 
        error = (*linesw[tp->t_line].l_open)(sc->sc_cdev, tp);
        if (error) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (error);
        }
 
        disc_optim(tp, &tp->t_termios, sc);
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 
        return (0);
 }
@@ -968,19 +963,17 @@ ucom_close(struct ucom_softc *sc)
                (sc->sc_callback->ucom_stop_read) (sc);
        }
 
-       lwkt_gettoken(&tty_token);
-       crit_enter();
+       lwkt_gettoken(&tp->t_token);
        (*linesw[tp->t_line].l_close)(tp, 0); /* XXX: flags */
        disc_optim(tp, &tp->t_termios, sc);
        ttyclose(tp);
-       crit_exit();
 
        if (tp->t_dev) {
                release_dev(tp->t_dev);
                tp->t_dev = NULL;
        }
        /* XXX: Detach wakeup */
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 
        return (error);
 }
@@ -1043,9 +1036,8 @@ ucom_dev_read(struct dev_read_args *ap)
 
        sc = 0;
 
-       lwkt_gettoken(&tty_token);
-
        tp = dev->si_tty;
+       lwkt_gettoken(&tp->t_token);
        KKASSERT(tp!=NULL);
        sc = tp->t_sc;
        KKASSERT(sc!=NULL);
@@ -1057,9 +1049,9 @@ ucom_dev_read(struct dev_read_args *ap)
        error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag);
        /*UCOM_MTX_UNLOCK(sc);*/
 
+       lwkt_reltoken(&tp->t_token);
        DPRINTF("error = %d\n", error);
 
-       lwkt_reltoken(&tty_token);
        return (error);
 }
 
@@ -1071,8 +1063,8 @@ ucom_dev_write(struct dev_write_args *ap)
        struct tty *tp;
        int error;
 
-       lwkt_gettoken(&tty_token);
        tp = dev->si_tty;
+       lwkt_gettoken(&tp->t_token);
        KKASSERT(tp!=NULL);
        sc = tp->t_sc;
        KKASSERT(sc!=NULL);
@@ -1084,9 +1076,9 @@ ucom_dev_write(struct dev_write_args *ap)
        error = (*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag);
        /*UCOM_MTX_UNLOCK(sc);*/
 
+       lwkt_reltoken(&tp->t_token);
        DPRINTF("ucomwrite: error = %d\n", error);
 
-       lwkt_reltoken(&tty_token);
        return (error);
 }
 
@@ -1103,12 +1095,12 @@ ucom_dev_ioctl(struct dev_ioctl_args *ap)
        int mynor;
 
        UCOM_MTX_LOCK(sc);
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
 
        mynor = minor(dev);
 
        if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                UCOM_MTX_UNLOCK(sc);
                return (EIO);
        }
@@ -1124,7 +1116,7 @@ ucom_dev_ioctl(struct dev_ioctl_args *ap)
                        ct = mynor & CALLOUT_MASK ? &sc->sc_lt_out : &sc->sc_lt_in;
                        break;
                default:
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        UCOM_MTX_UNLOCK(sc);
                        return (ENODEV);        /* /dev/nodev */
                }
@@ -1132,31 +1124,31 @@ ucom_dev_ioctl(struct dev_ioctl_args *ap)
                case TIOCSETA:
                        error = priv_check_cred(ap->a_cred, PRIV_ROOT, 0);
                        if (error != 0) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                UCOM_MTX_UNLOCK(sc);
                                return (error);
                        }
                        *ct = *(struct termios *)data;
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        UCOM_MTX_UNLOCK(sc);
                        return (0);
                case TIOCGETA:
                        *(struct termios *)data = *ct;
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        UCOM_MTX_UNLOCK(sc);
                        return (0);
                case TIOCGETD:
                        *(int *)data = TTYDISC;
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        UCOM_MTX_UNLOCK(sc);
                        return (0);
                case TIOCGWINSZ:
                        bzero(data, sizeof(struct winsize));
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        UCOM_MTX_UNLOCK(sc);
                        return (0);
                default:
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        UCOM_MTX_UNLOCK(sc);
                        return (ENOTTY);
                }
@@ -1167,19 +1159,16 @@ ucom_dev_ioctl(struct dev_ioctl_args *ap)
 
        if (error != ENOIOCTL) {
                DPRINTF("ucomioctl: l_ioctl: error = %d\n", error);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                UCOM_MTX_UNLOCK(sc);
                return (error);
        }
 
-       crit_enter();
-
        error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
        disc_optim(tp, &tp->t_termios, sc);
        if (error != ENOIOCTL) {
-               crit_exit();
                DPRINTF("ucomioctl: ttioctl: error = %d\n", error);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                UCOM_MTX_UNLOCK(sc);
 
                return (error);
@@ -1236,9 +1225,7 @@ ucom_dev_ioctl(struct dev_ioctl_args *ap)
                        error = (sc->sc_callback->ucom_ioctl)
                            (sc, cmd, data, 0, curthread);
                        if (error>=0) {
-                               crit_exit();
-
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                UCOM_MTX_UNLOCK(sc);
 
                                return(error);
@@ -1250,9 +1237,7 @@ ucom_dev_ioctl(struct dev_ioctl_args *ap)
                        error = pps_ioctl(cmd, data, &sc->sc_pps);
                break;
        }
-       crit_exit();
-
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        UCOM_MTX_UNLOCK(sc);
 
        return (error);
@@ -1658,7 +1643,7 @@ ucom_param(struct tty *tp, struct termios *t)
        uint8_t opened;
        int error;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        UCOM_MTX_ASSERT(sc, MA_OWNED);
 
        opened = 0;
@@ -1724,8 +1709,8 @@ done:
                        ucom_close(sc);
                }
        }
+       lwkt_reltoken(&tp->t_token);
 
-       lwkt_reltoken(&tty_token);
        return (error);
 }
 
@@ -1753,8 +1738,7 @@ ucom_start(struct tty *tp)
                return;
        }
 
-       lwkt_gettoken(&tty_token);
-       crit_enter();
+       lwkt_gettoken(&tp->t_token);
 
        if (tp->t_state & TS_TBLOCK) {
                if (ISSET(sc->sc_mcr, SER_RTS) &&
@@ -1799,8 +1783,7 @@ ucom_start(struct tty *tp)
        ttwwakeup(tp);
 
 out:
-       crit_exit();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        if (didlock)
                UCOM_MTX_UNLOCK(sc);
 }
@@ -1812,7 +1795,7 @@ ucom_stop(struct tty *tp, int flag)
 
        DPRINTF("sc = %p, x = 0x%x\n", sc, flag);
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        if (flag & FREAD) {
                /*   
                 * This is just supposed to flush pending receive data,
@@ -1833,17 +1816,15 @@ ucom_stop(struct tty *tp, int flag)
 
        if (flag & FWRITE) {
                DPRINTF("write\n");
-               crit_enter();
                if (ISSET(tp->t_state, TS_BUSY)) {
                        /* XXX do what? */
                        if (!ISSET(tp->t_state, TS_TTSTOP))
                                SET(tp->t_state, TS_FLUSH);
                }
-               crit_exit();
        }
 
        DPRINTF("done\n");
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*------------------------------------------------------------------------*
@@ -1912,8 +1893,7 @@ ucom_get_data(struct ucom_softc *sc, struct usb_page_cache *pc,
 
        offset_orig = offset;
 
-       lwkt_gettoken(&tty_token);
-       crit_enter();
+       lwkt_gettoken(&tp->t_token);
        while (len != 0) {
                usbd_get_page(pc, offset, &res);
 
@@ -1949,8 +1929,7 @@ ucom_get_data(struct ucom_softc *sc, struct usb_page_cache *pc,
                        break;
                }
        }
-       crit_exit();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 
        actlen[0] = offset - offset_orig;
 
@@ -1979,7 +1958,7 @@ ucom_put_data(struct ucom_softc *sc, struct usb_page_cache *pc,
        DPRINTF("\n");
 
        UCOM_MTX_ASSERT(sc, MA_OWNED);
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
 
        if (sc->sc_flag & UCOM_FLAG_CONSOLE) {
                unsigned int temp;
@@ -2006,22 +1985,21 @@ ucom_put_data(struct ucom_softc *sc, struct usb_page_cache *pc,
                ucom_cons_rx_high += temp;
                ucom_cons_rx_high %= UCOM_CONS_BUFSIZE;
 
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return;
        }
 
        if (tty_gone(tp)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return;                 /* multiport device polling */
        }
        if (len == 0) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return;                 /* no data */
        }
 
        /* set a flag to prevent recursation ? */
 
-       crit_enter();
        while (len > 0) {
                usbd_get_page(pc, offset, &res);
 
@@ -2114,8 +2092,7 @@ ucom_put_data(struct ucom_softc *sc, struct usb_page_cache *pc,
                        }
                }
        }
-       crit_exit();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        /*
        ttydisc_rint_done(tp);
        */
@@ -2315,12 +2292,12 @@ ucom_unref(struct ucom_super_softc *ssc)
 }
 
 /*
- * NOTE: Must be called with tty_token held.
+ * NOTE: Must be called with tp->t_token held.
  */
 static void
 disc_optim(struct tty *tp, struct termios *t, struct ucom_softc *sc)
 {
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
+       ASSERT_LWKT_TOKEN_HELD(&tp->t_token);
        if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON))
            && (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK))
            && (!(t->c_iflag & PARMRK)
index 56273bf..b4791e9 100644 (file)
@@ -131,7 +131,7 @@ atkbdresume(device_t dev)
         keyboard_t *kbd;
         int args[2];
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
         sc = device_get_softc(dev);
         kbd = kbd_get_keyboard(kbd_find_keyboard(ATKBD_DRIVER_NAME,
                                                  device_get_unit(dev)));
@@ -144,7 +144,7 @@ atkbdresume(device_t dev)
                kbd_clear_state(kbd);
 
         }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
         return 0;
 }
 
@@ -153,10 +153,10 @@ atkbd_isa_intr(void *arg)
 {
        keyboard_t *kbd;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        kbd = (keyboard_t *)arg;
        kbd_intr(kbd, NULL);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
 }
 
 DRIVER_MODULE(atkbd, atkbdc, atkbd_driver, atkbd_devclass, NULL, NULL);
index 38ddd60..073318c 100644 (file)
@@ -239,7 +239,7 @@ atkbdc_attach(device_t dev)
        int             rid;
        int             i;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        unit = device_get_unit(dev);
        sc = *(atkbdc_softc_t **)device_get_softc(dev);
        if (sc == NULL) {
@@ -252,7 +252,7 @@ atkbdc_attach(device_t dev)
                 */
                sc = atkbdc_get_softc(unit);
                if (sc == NULL) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return ENOMEM;
                }
        }
@@ -261,7 +261,7 @@ atkbdc_attach(device_t dev)
        sc->port0 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
                                       RF_ACTIVE);
        if (sc->port0 == NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return ENXIO;
        }
        rid = 1;
@@ -269,7 +269,7 @@ atkbdc_attach(device_t dev)
                                       RF_ACTIVE);
        if (sc->port1 == NULL) {
                bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return ENXIO;
        }
 
@@ -277,7 +277,7 @@ atkbdc_attach(device_t dev)
        if (error) {
                bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
                bus_release_resource(dev, SYS_RES_IOPORT, 1, sc->port1);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return error;
        }
        *(atkbdc_softc_t **)device_get_softc(dev) = sc;
@@ -304,7 +304,7 @@ atkbdc_attach(device_t dev)
 
        bus_generic_attach(dev);
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -331,7 +331,7 @@ atkbdc_read_ivar(device_t bus, device_t dev, int index, u_long *val)
 {
        atkbdc_device_t *ivar;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        ivar = (atkbdc_device_t *)device_get_ivars(dev);
        switch (index) {
        case KBDC_IVAR_IRQ:
@@ -353,11 +353,11 @@ atkbdc_read_ivar(device_t bus, device_t dev, int index, u_long *val)
                *val = (u_long)ivar->compatid;
                break;
        default:
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return ENOENT;
        }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -366,7 +366,7 @@ atkbdc_write_ivar(device_t bus, device_t dev, int index, u_long val)
 {
        atkbdc_device_t *ivar;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        ivar = (atkbdc_device_t *)device_get_ivars(dev);
        switch (index) {
        case KBDC_IVAR_IRQ:
@@ -388,11 +388,11 @@ atkbdc_write_ivar(device_t bus, device_t dev, int index, u_long val)
                ivar->compatid = (u_int32_t)val;
                break;
        default:
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return ENOENT;
        }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
index ca64e42..a53dcfb 100644 (file)
@@ -144,7 +144,6 @@ dcons_check_break(struct dcons_softc *dc, int c)
        if (c < 0)
                return (c);
 
-       lwkt_gettoken(&tty_token);
        switch (dc->brk_state) {
        case STATE1:
                if (c == KEY_TILDE)
@@ -164,7 +163,6 @@ dcons_check_break(struct dcons_softc *dc, int c)
        }
        if (c == KEY_CR)
                dc->brk_state = STATE1;
-       lwkt_reltoken(&tty_token);
        return (c);
 }
 #else
@@ -176,7 +174,6 @@ dcons_os_checkc(struct dcons_softc *dc)
 {
        int c;
 
-       lwkt_gettoken(&tty_token);
        if (dg.dma_tag != NULL)
                bus_dmamap_sync(dg.dma_tag, dg.dma_map, BUS_DMASYNC_POSTREAD);
   
@@ -185,7 +182,6 @@ dcons_os_checkc(struct dcons_softc *dc)
        if (dg.dma_tag != NULL)
                bus_dmamap_sync(dg.dma_tag, dg.dma_map, BUS_DMASYNC_PREREAD);
 
-       lwkt_reltoken(&tty_token);
        return (c);
 }
 
@@ -221,8 +217,8 @@ dcons_open(struct dev_open_args *ap)
        if (unit != 0)
                return (ENXIO);
 
-       lwkt_gettoken(&tty_token);
-       tp = dev->si_tty = ttymalloc(dev->si_tty);
+       tp = ttymalloc(&dev->si_tty);
+       lwkt_gettoken(&tp->t_token);
        tp->t_oproc = dcons_tty_start;
        tp->t_param = dcons_tty_param;
        tp->t_stop = nottystop;
@@ -230,7 +226,6 @@ dcons_open(struct dev_open_args *ap)
 
        error = 0;
 
-       crit_enter();
        if ((tp->t_state & TS_ISOPEN) == 0) {
                tp->t_state |= TS_CARR_ON;
                ttychars(tp);
@@ -241,14 +236,14 @@ dcons_open(struct dev_open_args *ap)
                tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
                ttsetwater(tp);
        } else if ((tp->t_state & TS_XCLUDE) && priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) {
-               crit_exit();
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
+
                return (EBUSY);
        }
-       crit_exit();
 
        error = (*linesw[tp->t_line].l_open)(dev, tp);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+
        return (error);
 }
 
@@ -263,13 +258,13 @@ dcons_close(struct dev_close_args *ap)
        if (unit != 0)
                return (ENXIO);
 
-       lwkt_gettoken(&tty_token);
        tp = dev->si_tty;
+       lwkt_gettoken(&tp->t_token);
        if (tp->t_state & TS_ISOPEN) {
                (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
                ttyclose(tp);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 
        return (0);
 }
@@ -286,32 +281,32 @@ dcons_ioctl(struct dev_ioctl_args *ap)
        if (unit != 0)
                return (ENXIO);
 
-       lwkt_gettoken(&tty_token);
        tp = dev->si_tty;
+       lwkt_gettoken(&tp->t_token);
        error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data, ap->a_fflag, ap->a_cred);
        if (error != ENOIOCTL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (error);
        }
 
        error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
        if (error != ENOIOCTL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (error);
        }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (ENOTTY);
 }
 
 static int
 dcons_tty_param(struct tty *tp, struct termios *t)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        tp->t_ispeed = t->c_ispeed;
        tp->t_ospeed = t->c_ospeed;
        tp->t_cflag = t->c_cflag;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return 0;
 }
 
@@ -320,13 +315,11 @@ dcons_tty_start(struct tty *tp)
 {
        struct dcons_softc *dc;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        dc = (struct dcons_softc *)tp->t_dev->si_drv1;
-       crit_enter();
        if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
                ttwwakeup(tp);
-               crit_exit();
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return;
        }
 
@@ -336,30 +329,30 @@ dcons_tty_start(struct tty *tp)
        tp->t_state &= ~TS_BUSY;
 
        ttwwakeup(tp);
-       crit_exit();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 static void
-dcons_timeout(void *v)
+dcons_timeout(void *dummy __unused)
 {
-       struct  tty *tp;
+       struct tty *tp;
        struct dcons_softc *dc;
        int i, c, polltime;
 
-       lwkt_gettoken(&tty_token);
        for (i = 0; i < DCONS_NPORT; i ++) {
                dc = &sc[i];
                tp = ((DEV)dc->dev)->si_tty;
-               while ((c = dcons_os_checkc(dc)) != -1)
+               lwkt_gettoken(&tp->t_token);
+               while ((c = dcons_os_checkc(dc)) != -1) {
                        if (tp->t_state & TS_ISOPEN)
                                (*linesw[tp->t_line].l_rint)(c, tp);
+               }
+               lwkt_reltoken(&tp->t_token);
        }
        polltime = hz / poll_hz;
        if (polltime < 1)
                polltime = 1;
-       callout_reset(&dcons_callout, polltime, dcons_timeout, tp);
-       lwkt_reltoken(&tty_token);
+       callout_reset(&dcons_callout, polltime, dcons_timeout, NULL);
 }
 
 static void
@@ -505,9 +498,6 @@ ok:
        return 0;
 }
 
-/*
- * NOTE: Must be called with tty_token held
- */
 static int
 dcons_attach_port(int port, char *name, int flags)
 {
@@ -515,17 +505,14 @@ dcons_attach_port(int port, char *name, int flags)
        struct tty *tp;
        DEV dev;
 
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
        dc = &sc[port];
        dc->flags = flags;
-       dev = make_dev(&dcons_ops, port, UID_ROOT, GID_WHEEL, 0600, "%s",
-           name);
+       dev = make_dev(&dcons_ops, port, UID_ROOT, GID_WHEEL, 0600,
+                      "%s", name);
        dc->dev = (void *)dev;
-       tp = ttymalloc(NULL);
-
        dev->si_drv1 = (void *)dc;
-       dev->si_tty = tp;
 
+       tp = ttymalloc(&dev->si_tty);
        tp->t_oproc = dcons_tty_start;
        tp->t_param = dcons_tty_param;
        tp->t_stop = nottystop;
@@ -534,15 +521,11 @@ dcons_attach_port(int port, char *name, int flags)
        return(0);
 }
 
-/*
- * NOTE: Must be called with tty_token held
- */
 static int
 dcons_attach(void)
 {
        int polltime;
 
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
        dcons_attach_port(DCONS_CON, "dcons", 0);
        dcons_attach_port(DCONS_GDB, "dgdb", DC_GDB);
        callout_init_mp(&dcons_callout);
@@ -553,19 +536,16 @@ dcons_attach(void)
        return(0);
 }
 
-/*
- * NOTE: Must be called with tty_token held
- */
 static int
 dcons_detach(int port)
 {
        struct  tty *tp;
        struct dcons_softc *dc;
 
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
        dc = &sc[port];
 
        tp = ((DEV)dc->dev)->si_tty;
+       lwkt_gettoken(&tp->t_token);
 
        if (tp->t_state & TS_ISOPEN) {
                kprintf("dcons: still opened\n");
@@ -580,6 +560,7 @@ dcons_detach(int port)
 #else
        tsleep((void *)dc, PWAIT, "dcodtc", hz/4);
 #endif
+       lwkt_reltoken(&tp->t_token);
        destroy_dev(dc->dev);
 
        return(0);
@@ -592,7 +573,6 @@ dcons_modevent(module_t mode, int type, void *data)
 {
        int err = 0, ret;
 
-       lwkt_gettoken(&tty_token);
        switch (type) {
        case MOD_LOAD:
                ret = dcons_drv_init(1);
@@ -633,7 +613,6 @@ dcons_modevent(module_t mode, int type, void *data)
                err = EOPNOTSUPP;
                break;
        }
-       lwkt_reltoken(&tty_token);
        return(err);
 }
 
index 815dae0..0e5b951 100644 (file)
  */
 /*
  * Generic keyboard driver.
- *
- * Interrupt note: keyboards use clist functions and since usb keyboard
- * interrupts are not protected by spltty(), we must use a critical section
- * to protect against corruption.
- * XXX: this keyboard driver doesn't use clist functions anymore!
- *
- * MPSAFE NOTE: all keyboards could easily be put under a different global token.
  */
 
 #include "opt_kbd.h"
@@ -106,7 +99,7 @@ kbd_realloc_array(void)
        keyboard_switch_t **new_kbdsw;
        int newsize;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        newsize = ((keyboards + ARRAY_DELTA)/ARRAY_DELTA)*ARRAY_DELTA;
        new_kbd = kmalloc(sizeof(*new_kbd) * newsize, M_DEVBUF,
                                M_WAITOK | M_ZERO);
@@ -114,7 +107,6 @@ kbd_realloc_array(void)
                                M_WAITOK | M_ZERO);
        bcopy(keyboard, new_kbd, sizeof(*keyboard)*keyboards);
        bcopy(kbdsw, new_kbdsw, sizeof(*kbdsw)*keyboards);
-       crit_enter();
        if (keyboards > 1) {
                kfree(keyboard, M_DEVBUF);
                kfree(kbdsw, M_DEVBUF);
@@ -122,12 +114,11 @@ kbd_realloc_array(void)
        keyboard = new_kbd;
        kbdsw = new_kbdsw;
        keyboards = newsize;
-       crit_exit();
 
        if (bootverbose)
                kprintf("kbd: new array size %d\n", keyboards);
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -147,7 +138,7 @@ kbd_realloc_array(void)
 void
 kbd_reinit_struct(keyboard_t *kbd, int config, int pref)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        kbd->kb_flags |= KB_NO_DEVICE;  /* device has not been found */
        kbd->kb_config = config & ~KB_CONF_PROBE_ONLY;
        kbd->kb_led = 0;                /* unknown */
@@ -161,7 +152,7 @@ kbd_reinit_struct(keyboard_t *kbd, int config, int pref)
        kbd->kb_count = 0;
        kbd->kb_pref = pref;
        bzero(kbd->kb_lastact, sizeof(kbd->kb_lastact));
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
 }
 
 /* initialize the keyboard_t structure */
@@ -169,7 +160,7 @@ void
 kbd_init_struct(keyboard_t *kbd, char *name, int type, int unit, int config,
                int pref, int port, int port_size)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        kbd->kb_flags = 0;
        kbd->kb_name = name;
        kbd->kb_type = type;
@@ -178,42 +169,42 @@ kbd_init_struct(keyboard_t *kbd, char *name, int type, int unit, int config,
        kbd->kb_io_size = port_size;
        kbd_reinit_struct(kbd, config, pref);
        lockinit(&kbd->kb_lock, name, 0, LK_CANRECURSE);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
 }
 
 void
 kbd_set_maps(keyboard_t *kbd, keymap_t *keymap, accentmap_t *accmap,
             fkeytab_t *fkeymap, int fkeymap_size)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        kbd->kb_keymap = keymap;
        kbd->kb_accentmap = accmap;
        kbd->kb_fkeytab = fkeymap;
        kbd->kb_fkeytab_size = fkeymap_size;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
 }
 
 /* declare a new keyboard driver */
 int
 kbd_add_driver(keyboard_driver_t *driver)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        if (SLIST_NEXT(driver, link)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return EINVAL;
        }
        SLIST_INSERT_HEAD(&keyboard_drivers, driver, link);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
 int
 kbd_delete_driver(keyboard_driver_t *driver)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        SLIST_REMOVE(&keyboard_drivers, driver, keyboard_driver, link);
        SLIST_NEXT(driver, link) = NULL;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -227,7 +218,7 @@ kbd_register(keyboard_t *kbd)
        keyboard_info_t ki;
        int index;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        mux = kbd_get_keyboard(kbd_find_keyboard("kbdmux", -1));
 
        for (index = 0; index < keyboards; ++index) {
@@ -236,7 +227,7 @@ kbd_register(keyboard_t *kbd)
        }
        if (index >= keyboards) {
                if (kbd_realloc_array()) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return -1;
                }
        }
@@ -262,7 +253,7 @@ kbd_register(keyboard_t *kbd)
                                kbd_ioctl(mux, KBADDKBD, (caddr_t) &ki);
                        }
 
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return index;
                }
        }
@@ -279,12 +270,12 @@ kbd_register(keyboard_t *kbd)
                                kbd_ioctl(mux, KBADDKBD, (caddr_t) &ki);
                        }
 
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return index;
                }
        }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return -1;
 }
 
@@ -294,29 +285,26 @@ kbd_unregister(keyboard_t *kbd)
        int error;
 
        KBD_LOCK_ASSERT(kbd);
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        if ((kbd->kb_index < 0) || (kbd->kb_index >= keyboards)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return ENOENT;
        }
        if (keyboard[kbd->kb_index] != kbd) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return ENOENT;
        }
 
-       crit_enter();
        callout_stop(&kbd->kb_atkbd_timeout_ch);
        if (KBD_IS_BUSY(kbd)) {
                error = (*kbd->kb_callback.kc_func)(kbd, KBDIO_UNLOADING,
                                                    kbd->kb_callback.kc_arg);
                if (error) {
-                       crit_exit();
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return error;
                }
                if (KBD_IS_BUSY(kbd)) {
-                       crit_exit();
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return EBUSY;
                }
        }
@@ -328,8 +316,7 @@ kbd_unregister(keyboard_t *kbd)
        KBD_ALWAYS_UNLOCK(kbd);
        lockuninit(&kbd->kb_lock);
 
-       crit_exit();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -340,23 +327,23 @@ kbd_get_switch(char *driver)
        const keyboard_driver_t **list;
        const keyboard_driver_t *p;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
 
        SLIST_FOREACH(p, &keyboard_drivers, link) {
                if (strcmp(p->name, driver) == 0) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return p->kbdsw;
                }
        }
        SET_FOREACH(list, kbddriver_set) {
                p = *list;
                if (strcmp(p->name, driver) == 0) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return p->kbdsw;
                }
        }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return NULL;
 }
 
@@ -380,9 +367,9 @@ kbd_find_keyboard2(char *driver, int unit, int index, int legacy)
        pref = 0;
        pref_index = -1;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        if ((index < 0) || (index >= keyboards)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return (-1);
        }
 
@@ -405,7 +392,7 @@ kbd_find_keyboard2(char *driver, int unit, int index, int legacy)
                                pref_index = i;
                        }
                } else {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return i;
                }
        }
@@ -413,7 +400,7 @@ kbd_find_keyboard2(char *driver, int unit, int index, int legacy)
        if (!legacy)
                KKASSERT(pref_index == -1);
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return (pref_index);
 }
 
@@ -434,14 +421,12 @@ kbd_allocate(char *driver, int unit, void *id, kbd_callback_func_t *func,
        if (func == NULL)
                return -1;
 
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
 
        index = kbd_find_keyboard(driver, unit);
        if (index >= 0) {
                if (KBD_IS_BUSY(keyboard[index])) {
-                       crit_exit();
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return -1;
                }
                keyboard[index]->kb_token = id;
@@ -451,8 +436,7 @@ kbd_allocate(char *driver, int unit, void *id, kbd_callback_func_t *func,
                kbd_clear_state(keyboard[index]);
        }
 
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&kbd_token);
        return index;
 }
 
@@ -461,8 +445,7 @@ kbd_release(keyboard_t *kbd, void *id)
 {
        int error;
 
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
 
        if (!KBD_IS_VALID(kbd) || !KBD_IS_BUSY(kbd)) {
                error = EINVAL;
@@ -477,8 +460,7 @@ kbd_release(keyboard_t *kbd, void *id)
                error = 0;
        }
 
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&kbd_token);
        return error;
 }
 
@@ -488,8 +470,7 @@ kbd_change_callback(keyboard_t *kbd, void *id, kbd_callback_func_t *func,
 {
        int error;
 
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
 
        if (!KBD_IS_VALID(kbd) || !KBD_IS_BUSY(kbd)) {
                error = EINVAL;
@@ -503,8 +484,7 @@ kbd_change_callback(keyboard_t *kbd, void *id, kbd_callback_func_t *func,
                error = 0;
        }
 
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&kbd_token);
        return error;
 }
 
@@ -514,21 +494,21 @@ kbd_get_keyboard(int index)
 {
        keyboard_t *kbd;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        if ((index < 0) || (index >= keyboards)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return NULL;
        }
        if (keyboard[index] == NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return NULL;
        }
        if (!KBD_IS_VALID(keyboard[index])) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return NULL;
        }
        kbd = keyboard[index];
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
 
        return kbd;
 }
@@ -545,7 +525,7 @@ kbd_configure(int flags)
        const keyboard_driver_t **list;
        const keyboard_driver_t *p;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
 
        SLIST_FOREACH(p, &keyboard_drivers, link) {
                if (p->configure != NULL)
@@ -557,7 +537,7 @@ kbd_configure(int flags)
                        (*p->configure)(flags);
        }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -603,13 +583,13 @@ kbd_attach(keyboard_t *kbd)
        cdev_t dev;
        char tbuf[MAKEDEV_MINNBUF];
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        if (kbd->kb_index >= keyboards) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return EINVAL;
        }
        if (keyboard[kbd->kb_index] != kbd) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return EINVAL;
        }
 
@@ -626,7 +606,7 @@ kbd_attach(keyboard_t *kbd)
        bzero(dev->si_drv1, sizeof(struct genkbd_softc));
 
        kprintf("kbd%d at %s%d\n", kbd->kb_index, kbd->kb_name, kbd->kb_unit);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -635,14 +615,14 @@ kbd_detach(keyboard_t *kbd)
 {
        cdev_t dev;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
 
        if (kbd->kb_index >= keyboards) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return EINVAL;
        }
        if (keyboard[kbd->kb_index] != kbd) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return EINVAL;
        }
 
@@ -654,7 +634,7 @@ kbd_detach(keyboard_t *kbd)
                kbd->kb_dev = NULL;
        }
        dev_ops_remove_minor(&kbd_ops, kbd->kb_index);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -669,10 +649,10 @@ genkbd_putc(genkbd_softc_t sc, char c)
 {
        unsigned int p;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
 
        if (sc->gkb_q_length == KB_QSIZE) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return;
        }
 
@@ -680,18 +660,18 @@ genkbd_putc(genkbd_softc_t sc, char c)
        sc->gkb_q[p] = c;
        sc->gkb_q_length++;
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
 }
 
 static size_t
 genkbd_getc(genkbd_softc_t sc, char *buf, size_t len)
 {
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
 
        /* Determine copy size. */
        if (sc->gkb_q_length == 0) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return (0);
        }
        if (len >= sc->gkb_q_length)
@@ -704,7 +684,7 @@ genkbd_getc(genkbd_softc_t sc, char *buf, size_t len)
        sc->gkb_q_start = (sc->gkb_q_start + len) % KB_QSIZE;
        sc->gkb_q_length -= len;
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return (len);
 }
 
@@ -718,20 +698,17 @@ genkbdopen(struct dev_open_args *ap)
        genkbd_softc_t sc;
        int i;
 
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        sc = dev->si_drv1;
        kbd = kbd_get_keyboard(KBD_INDEX(dev));
        if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) {
-               lwkt_reltoken(&tty_token);
-               crit_exit();
+               lwkt_reltoken(&kbd_token);
                return ENXIO;
        }
        i = kbd_allocate(kbd->kb_name, kbd->kb_unit, sc,
                         genkbd_event, sc);
        if (i < 0) {
-               lwkt_reltoken(&tty_token);
-               crit_exit();
+               lwkt_reltoken(&kbd_token);
                return EBUSY;
        }
        /* assert(i == kbd->kb_index) */
@@ -743,8 +720,7 @@ genkbdopen(struct dev_open_args *ap)
         */
 
        sc->gkb_q_length = 0;
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&kbd_token);
 
        return 0;
 }
@@ -760,8 +736,7 @@ genkbdclose(struct dev_close_args *ap)
         * NOTE: the device may have already become invalid.
         * kbd == NULL || !KBD_IS_VALID(kbd)
         */
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        sc = dev->si_drv1;
        kbd = kbd_get_keyboard(KBD_INDEX(dev));
        if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) {
@@ -769,8 +744,7 @@ genkbdclose(struct dev_close_args *ap)
        } else {
                kbd_release(kbd, sc);
        }
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -786,38 +760,32 @@ genkbdread(struct dev_read_args *ap)
        int error;
 
        /* wait for input */
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        sc = dev->si_drv1;
        kbd = kbd_get_keyboard(KBD_INDEX(dev));
        if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) {
-               lwkt_reltoken(&tty_token);
-               crit_exit();
+               lwkt_reltoken(&kbd_token);
                return ENXIO;
        }
        while (sc->gkb_q_length == 0) {
                if (ap->a_ioflag & IO_NDELAY) { /* O_NONBLOCK? */
-                       lwkt_reltoken(&tty_token);
-                       crit_exit();
+                       lwkt_reltoken(&kbd_token);
                        return EWOULDBLOCK;
                }
                sc->gkb_flags |= KB_ASLEEP;
                error = tsleep((caddr_t)sc, PCATCH, "kbdrea", 0);
                kbd = kbd_get_keyboard(KBD_INDEX(dev));
                if ((kbd == NULL) || !KBD_IS_VALID(kbd)) {
-                       lwkt_reltoken(&tty_token);
-                       crit_exit();
+                       lwkt_reltoken(&kbd_token);
                        return ENXIO;   /* our keyboard has gone... */
                }
                if (error) {
                        sc->gkb_flags &= ~KB_ASLEEP;
-                       lwkt_reltoken(&tty_token);
-                       crit_exit();
+                       lwkt_reltoken(&kbd_token);
                        return error;
                }
        }
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&kbd_token);
 
        /* copy as much input as possible */
        error = 0;
@@ -840,13 +808,13 @@ genkbdwrite(struct dev_write_args *ap)
        cdev_t dev = ap->a_head.a_dev;
        keyboard_t *kbd;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        kbd = kbd_get_keyboard(KBD_INDEX(dev));
        if ((kbd == NULL) || !KBD_IS_VALID(kbd)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return ENXIO;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return ENODEV;
 }
 
@@ -857,17 +825,17 @@ genkbdioctl(struct dev_ioctl_args *ap)
        keyboard_t *kbd;
        int error;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        kbd = kbd_get_keyboard(KBD_INDEX(dev));
        if ((kbd == NULL) || !KBD_IS_VALID(kbd)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return ENXIO;
        }
        error = kbd_ioctl(kbd, ap->a_cmd, ap->a_data);
        if (error == ENOIOCTL)
                error = ENODEV;
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return error;
 }
 
@@ -921,8 +889,7 @@ genkbdfilter(struct knote *kn, long hint)
        genkbd_softc_t sc;
        int ready = 0;
 
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        sc = dev->si_drv1;
         kbd = kbd_get_keyboard(KBD_INDEX(dev));
        if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) {
@@ -933,8 +900,7 @@ genkbdfilter(struct knote *kn, long hint)
                if (sc->gkb_q_length > 0)
                         ready = 1;
         }
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&kbd_token);
 
        return (ready);
 }
@@ -948,7 +914,7 @@ genkbd_event(keyboard_t *kbd, int event, void *arg)
        int mode;
        int c;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        /* assert(KBD_IS_VALID(kbd)) */
        sc = (genkbd_softc_t)arg;
 
@@ -963,10 +929,10 @@ genkbd_event(keyboard_t *kbd, int event, void *arg)
                        wakeup((caddr_t)sc);
                }
                KNOTE(&sc->gkb_rkq.ki_note, 0);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return 0;
        default:
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return EINVAL;
        }
 
@@ -1037,7 +1003,7 @@ genkbd_event(keyboard_t *kbd, int event, void *arg)
                KNOTE(&sc->gkb_rkq.ki_note, 0);
        }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -1056,8 +1022,7 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
        fkeyarg_t *fkeyp;
        int i;
 
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        switch (cmd) {
 
        case KDGKBINFO:         /* get keyboard information */
@@ -1089,8 +1054,7 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                bcopy(arg, kbd->kb_keymap, sizeof(*kbd->kb_keymap));
                break;
 #else
-               lwkt_reltoken(&tty_token);
-               crit_exit();
+               lwkt_reltoken(&kbd_token);
                return ENODEV;
 #endif
 
@@ -1098,8 +1062,7 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                keyp = (keyarg_t *)arg;
                if (keyp->keynum >= sizeof(kbd->kb_keymap->key)
                                        /sizeof(kbd->kb_keymap->key[0])) {
-                       lwkt_reltoken(&tty_token);
-                       crit_exit();
+                       lwkt_reltoken(&kbd_token);
                        return EINVAL;
                }
                bcopy(&kbd->kb_keymap->key[keyp->keynum], &keyp->key,
@@ -1110,16 +1073,14 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                keyp = (keyarg_t *)arg;
                if (keyp->keynum >= sizeof(kbd->kb_keymap->key)
                                        /sizeof(kbd->kb_keymap->key[0])) {
-                       lwkt_reltoken(&tty_token);
-                       crit_exit();
+                       lwkt_reltoken(&kbd_token);
                        return EINVAL;
                }
                bcopy(&keyp->key, &kbd->kb_keymap->key[keyp->keynum],
                      sizeof(keyp->key));
                break;
 #else
-               lwkt_reltoken(&tty_token);
-               crit_exit();
+               lwkt_reltoken(&kbd_token);
                return ENODEV;
 #endif
 
@@ -1131,16 +1092,14 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                bcopy(arg, kbd->kb_accentmap, sizeof(*kbd->kb_accentmap));
                break;
 #else
-               lwkt_reltoken(&tty_token);
-               crit_exit();
+               lwkt_reltoken(&kbd_token);
                return ENODEV;
 #endif
 
        case GETFKEY:           /* get functionkey string */
                fkeyp = (fkeyarg_t *)arg;
                if (fkeyp->keynum >= kbd->kb_fkeytab_size) {
-                       lwkt_reltoken(&tty_token);
-                       crit_exit();
+                       lwkt_reltoken(&kbd_token);
                        return EINVAL;
                }
                bcopy(kbd->kb_fkeytab[fkeyp->keynum].str, fkeyp->keydef,
@@ -1151,8 +1110,7 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
 #ifndef KBD_DISABLE_KEYMAP_LOAD
                fkeyp = (fkeyarg_t *)arg;
                if (fkeyp->keynum >= kbd->kb_fkeytab_size) {
-                       lwkt_reltoken(&tty_token);
-                       crit_exit();
+                       lwkt_reltoken(&kbd_token);
                        return EINVAL;
                }
                kbd->kb_fkeytab[fkeyp->keynum].len = imin(fkeyp->flen, MAXFK);
@@ -1160,19 +1118,16 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                      kbd->kb_fkeytab[fkeyp->keynum].len);
                break;
 #else
-               lwkt_reltoken(&tty_token);
-               crit_exit();
+               lwkt_reltoken(&kbd_token);
                return ENODEV;
 #endif
 
        default:
-               lwkt_reltoken(&tty_token);
-               crit_exit();
+               lwkt_reltoken(&kbd_token);
                return ENOIOCTL;
        }
 
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&kbd_token);
        return 0;
 }
 
@@ -1185,16 +1140,16 @@ genkbd_get_fkeystr(keyboard_t *kbd, int fkey, size_t *len)
        if (kbd == NULL)
                return NULL;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        fkey -= F_FN;
        if (fkey > kbd->kb_fkeytab_size) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return NULL;
        }
        *len = kbd->kb_fkeytab[fkey].len;
        ch = kbd->kb_fkeytab[fkey].str;
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return ch;
 }
 
@@ -1248,14 +1203,14 @@ save_accent_key(keyboard_t *kbd, u_int key, int *accents)
 {
        int i;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        /* make an index into the accent map */
        i = key - F_ACC + 1;
        if ((i > kbd->kb_accentmap->n_accs)
            || (kbd->kb_accentmap->acc[i - 1].accchar == 0)) {
                /* the index is out of range or pointing to an empty entry */
                *accents = 0;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return ERRKEY;
        }
 
@@ -1266,13 +1221,13 @@ save_accent_key(keyboard_t *kbd, u_int key, int *accents)
        if (i == *accents) {
                key = kbd->kb_accentmap->acc[i - 1].accchar;
                *accents = 0;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return key;
        }
 
        /* remember the index and wait for the next key  */
        *accents = i; 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        return NOKEY;
 }
 
@@ -1282,7 +1237,7 @@ make_accent_char(keyboard_t *kbd, u_int ch, int *accents)
        struct acc_t *acc;
        int i;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        acc = &kbd->kb_accentmap->acc[*accents - 1];
        *accents = 0;
 
@@ -1291,7 +1246,7 @@ make_accent_char(keyboard_t *kbd, u_int ch, int *accents)
         * produce the accent char itself.
         */
        if (ch == ' ') {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return acc->accchar;
        }
 
@@ -1300,11 +1255,11 @@ make_accent_char(keyboard_t *kbd, u_int ch, int *accents)
                if (acc->map[i][0] == 0)        /* end of table */
                        break;
                if (acc->map[i][0] == ch) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return acc->map[i][1];
                }
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
        /* this char cannot be accented... */
        return ERRKEY;
 }
@@ -1319,7 +1274,7 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate,
        int f;
        int i;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&kbd_token);
        i = keycode;
        f = state & (AGRS | ALKED);
        if ((f == AGRS1) || (f == AGRS2) || (f == ALKED))
@@ -1417,11 +1372,11 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate,
                case NOP:
                        /* release events of regular keys are not reported */
                        *shiftstate &= ~SHIFTAON;
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return NOKEY;
                }
                *shiftstate = state & ~SHIFTAON;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&kbd_token);
                return (SPCLKEY | RELKEY | action);
        } else {        /* make: key pressed */
                action = key->map[i];
@@ -1506,7 +1461,7 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate,
                                break;
                        case NOP:
                                *shiftstate = state;
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&kbd_token);
                                return NOKEY;
                        default:
                                /* is this an accent (dead) key? */
@@ -1517,14 +1472,14 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate,
                                        switch (action) {
                                        case NOKEY:
                                        case ERRKEY:
-                                               lwkt_reltoken(&tty_token);
+                                               lwkt_reltoken(&kbd_token);
                                                return action;
                                        default:
                                                if (state & METAS) {
-                                                       lwkt_reltoken(&tty_token);
+                                                       lwkt_reltoken(&kbd_token);
                                                        return (action | MKEY);
                                                } else { 
-                                                       lwkt_reltoken(&tty_token);
+                                                       lwkt_reltoken(&kbd_token);
                                                        return action;
                                                }
                                        }
@@ -1533,17 +1488,17 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate,
                                /* other special keys */
                                if (*accents > 0) {
                                        *accents = 0;
-                                       lwkt_reltoken(&tty_token);
+                                       lwkt_reltoken(&kbd_token);
                                        return ERRKEY;
                                }
                                if (action >= F_FN && action <= L_FN)
                                        action |= FKEY;
                                /* XXX: return fkey string for the FKEY? */
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&kbd_token);
                                return (SPCLKEY | action);
                        }
                        *shiftstate = state;
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return (SPCLKEY | action);
                } else {
                        /* regular keys */
@@ -1553,16 +1508,16 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate,
                                /* make an accented char */
                                action = make_accent_char(kbd, action, accents);
                                if (action == ERRKEY) {
-                                       lwkt_reltoken(&tty_token);
+                                       lwkt_reltoken(&kbd_token);
                                        return action;
                                }
                        }
                        if (state & METAS)
                                action |= MKEY;
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&kbd_token);
                        return action;
                }
        }
        /* NOT REACHED */
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&kbd_token);
 }
index b6c01b6..afbef21 100644 (file)
  * $FreeBSD: src/sys/dev/nmdm/nmdm.c,v 1.5.2.1 2001/08/11 00:54:14 mp Exp $
  */
 
-/*
- * MPSAFE NOTE: This file acquires the tty_token mainly for linesw access and
- *             tp (struct tty) access.
- */
-
 /*
  * Pseudo-nulmodem Driver
  */
@@ -114,8 +109,6 @@ do {        \
 
 /*
  * This function creates and initializes a pair of ttys.
- *
- * NOTE: Must be called with tty_token held
  */
 static void
 nmdminit(int n)
@@ -130,8 +123,6 @@ nmdminit(int n)
        if (n & ~0x7f)
                return;
 
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
-
        pt = kmalloc(sizeof(*pt), M_NLMDM, M_WAITOK | M_ZERO);
        pt->part1.dev = dev1 = make_dev(&nmdm_ops, n << 1,
                                        0, 0, 0666, "nmdm%dA", n);
@@ -141,6 +132,8 @@ nmdminit(int n)
        dev1->si_drv1 = dev2->si_drv1 = pt;
        dev1->si_tty = &pt->part1.nm_tty;
        dev2->si_tty = &pt->part2.nm_tty;
+       ttyinit(&pt->part1.nm_tty);
+       ttyinit(&pt->part2.nm_tty);
        ttyregister(&pt->part1.nm_tty);
        ttyregister(&pt->part2.nm_tty);
        pt->part1.nm_tty.t_oproc = nmdmstart;
@@ -190,14 +183,15 @@ nmdmopen(struct dev_open_args *ap)
        if (!dev->si_drv1)
                return(ENXIO);  
 
-       lwkt_gettoken(&tty_token);
        pti = dev->si_drv1;
        if (is_b) 
                tp = &pti->part2.nm_tty;
        else 
                tp = &pti->part1.nm_tty;
+       lwkt_gettoken(&tp->t_token);
        GETPARTS(tp, ourpart, otherpart);
        tp2 = &otherpart->nm_tty;
+       lwkt_gettoken(&tp2->t_token);
        ourpart->modemsignals |= TIOCM_LE;
 
        if ((tp->t_state & TS_ISOPEN) == 0) {
@@ -208,10 +202,14 @@ nmdmopen(struct dev_open_args *ap)
                tp->t_cflag = TTYDEF_CFLAG;
                tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
        } else if (tp->t_state & TS_XCLUDE && priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp2->t_token);
+               lwkt_reltoken(&tp->t_token);
+
                return (EBUSY);
        } else if (pti->pt_prison != ap->a_cred->cr_prison) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp2->t_token);
+               lwkt_reltoken(&tp->t_token);
+
                return (EBUSY);
        }
 
@@ -239,7 +237,9 @@ nmdmopen(struct dev_open_args *ap)
                        break;
                error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "nmdopn", 0);
                if (error) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp2->t_token);
+                       lwkt_reltoken(&tp->t_token);
+
                        return (error);
                }
        }
@@ -258,7 +258,9 @@ nmdmopen(struct dev_open_args *ap)
        nmdm_crossover(pti, ourpart, otherpart);
        if (error == 0)
                wakeup_other(tp, FREAD|FWRITE); /* XXX */
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp2->t_token);
+       lwkt_reltoken(&tp->t_token);
+
        return (error);
 }
 
@@ -270,13 +272,14 @@ nmdmclose(struct dev_close_args *ap)
        int err;
        struct softpart *ourpart, *otherpart;
 
-       lwkt_gettoken(&tty_token);
        /*
         * let the other end know that the game is up
         */
        tp = dev->si_tty;
+       lwkt_gettoken(&tp->t_token);
        GETPARTS(tp, ourpart, otherpart);
        tp2 = &otherpart->nm_tty;
+       lwkt_gettoken(&tp2->t_token);
        (void)(*linesw[tp2->t_line].l_modem)(tp2, 0);
 
        /*
@@ -297,8 +300,10 @@ nmdmclose(struct dev_close_args *ap)
        ourpart->modemsignals &= ~TIOCM_DTR;
        nmdm_crossover(dev->si_drv1, ourpart, otherpart);
        nmdmstop(tp, FREAD|FWRITE);
-       (void) ttyclose(tp);
-       lwkt_reltoken(&tty_token);
+       ttyclose(tp);
+       lwkt_reltoken(&tp2->t_token);
+       lwkt_reltoken(&tp->t_token);
+
        return (err);
 }
 
@@ -313,28 +318,32 @@ nmdmread(struct dev_read_args *ap)
        struct softpart *ourpart, *otherpart;
 #endif
 
-       lwkt_gettoken(&tty_token);
        tp = dev->si_tty;
+       lwkt_gettoken(&tp->t_token);
 #if 0
        GETPARTS(tp, ourpart, otherpart);
        tp2 = &otherpart->nm_tty;
+       lwkt_gettoken(&tp2->t_token);
 
        if (tp2->t_state & TS_ISOPEN) {
                error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, flag);
                wakeup_other(tp, FWRITE);
        } else {
                if (flag & IO_NDELAY) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp2->t_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (EWOULDBLOCK);
                }
                error = tsleep(TSA_PTC_READ(tp), PCATCH, "nmdout", 0);
                }
        }
+       lwkt_reltoken(&tp2->t_token);
 #else
        if ((error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag)) == 0)
                wakeup_other(tp, FWRITE);
 #endif
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+
        return (error);
 }
 
@@ -356,18 +365,20 @@ nmdmwrite(struct dev_write_args *ap)
        struct tty *tp1, *tp;
        struct softpart *ourpart, *otherpart;
 
-       lwkt_gettoken(&tty_token);
        tp1 = dev->si_tty;
+       lwkt_gettoken(&tp1->t_token);
        /*
         * Get the other tty struct.
         * basically we are writing into the INPUT side of the other device.
         */
        GETPARTS(tp1, ourpart, otherpart);
        tp = &otherpart->nm_tty;
+       lwkt_gettoken(&tp->t_token);
 
 again:
        if ((tp->t_state & TS_ISOPEN) == 0) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
+               lwkt_reltoken(&tp1->t_token);
                return (EIO);
        }
        while (uio->uio_resid > 0 || cc > 0) {
@@ -379,14 +390,16 @@ again:
                        cp = locbuf;
                        error = uiomove((caddr_t)cp, cc, uio);
                        if (error) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
+                               lwkt_reltoken(&tp1->t_token);
                                return (error);
                        }
                        /* check again for safety */
                        if ((tp->t_state & TS_ISOPEN) == 0) {
                                /* adjust for data copied in but not written */
                                uio->uio_resid += cc;
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
+                               lwkt_reltoken(&tp1->t_token);
                                return (EIO);
                        }
                }
@@ -405,7 +418,8 @@ again:
                                         * not written.
                                         */
                                        uio->uio_resid += cc;
-                                       lwkt_reltoken(&tty_token);
+                                       lwkt_reltoken(&tp->t_token);
+                                       lwkt_reltoken(&tp1->t_token);
                                        return (EIO);
                                }
                                if (ap->a_ioflag & IO_NDELAY) {
@@ -416,10 +430,12 @@ again:
                                         */
                                        uio->uio_resid += cc;
                                        if (cnt == 0) {
-                                               lwkt_reltoken(&tty_token);
+                                               lwkt_reltoken(&tp->t_token);
+                                               lwkt_reltoken(&tp1->t_token);
                                                return (EWOULDBLOCK);
                                        }
-                                       lwkt_reltoken(&tty_token);
+                                       lwkt_reltoken(&tp->t_token);
+                                       lwkt_reltoken(&tp1->t_token);
                                        return (0);
                                }
                                error = tsleep(TSA_PTC_WRITE(tp),
@@ -432,7 +448,8 @@ again:
                                         * not written
                                         */
                                        uio->uio_resid += cc;
-                                       lwkt_reltoken(&tty_token);
+                                       lwkt_reltoken(&tp->t_token);
+                                       lwkt_reltoken(&tp1->t_token);
                                        return (error);
                                }
                                goto again;
@@ -443,7 +460,9 @@ again:
                }
                cc = 0;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+       lwkt_reltoken(&tp1->t_token);
+
        return (0);
 }
 
@@ -456,24 +475,26 @@ nmdmstart(struct tty *tp)
 {
        struct nm_softc *pti = tp->t_dev->si_drv1;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        if (tp->t_state & TS_TTSTOP) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return;
        }
        pti->pt_flags &= ~PF_STOPPED;
        wakeup_other(tp, FREAD);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
-/* Wakes up the OTHER tty;*/
+/*
+ * Wakes up the OTHER tty.  Caller must hold at least tp->t_token.
+ */
 static void
 wakeup_other(struct tty *tp, int flag)
 {
        struct softpart *ourpart, *otherpart;
 
-       lwkt_gettoken(&tty_token);
        GETPARTS(tp, ourpart, otherpart);
+       lwkt_gettoken(&otherpart->nm_tty.t_token);
        if (flag & FREAD) {
                wakeup(TSA_PTC_READ((&otherpart->nm_tty)));
                KNOTE(&otherpart->nm_tty.t_rkq.ki_note, 0);
@@ -482,7 +503,7 @@ wakeup_other(struct tty *tp, int flag)
                wakeup(TSA_PTC_WRITE((&otherpart->nm_tty)));
                KNOTE(&otherpart->nm_tty.t_wkq.ki_note, 0);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&otherpart->nm_tty.t_token);
 }
 
 static void
@@ -491,7 +512,7 @@ nmdmstop(struct tty *tp, int flush)
        struct nm_softc *pti = tp->t_dev->si_drv1;
        int flag;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        /* note: FLUSHREAD and FLUSHWRITE already ok */
        if (flush == 0) {
                flush = TIOCPKT_STOP;
@@ -505,7 +526,7 @@ nmdmstop(struct tty *tp, int flush)
        if (flush & FWRITE)
                flag |= FREAD;
        wakeup_other(tp, flag);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*ARGSUSED*/
@@ -514,13 +535,15 @@ nmdmioctl(struct dev_ioctl_args *ap)
 {
        cdev_t dev = ap->a_head.a_dev;
        struct tty *tp = dev->si_tty;
+       struct tty *tp2;
        struct nm_softc *pti = dev->si_drv1;
        int error;
        struct softpart *ourpart, *otherpart;
 
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        GETPARTS(tp, ourpart, otherpart);
+       tp2 = &otherpart->nm_tty;
+       lwkt_gettoken(&tp2->t_token);
 
        error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data,
                                              ap->a_fflag, ap->a_cred);
@@ -561,31 +584,33 @@ nmdmioctl(struct dev_ioctl_args *ap)
                case TIOCTIMESTAMP:
                case TIOCDCDTIMESTAMP:
                default:
-                       lwkt_reltoken(&tty_token);
-                       crit_exit();
+                       lwkt_reltoken(&tp2->t_token);
+                       lwkt_reltoken(&tp->t_token);
                        error = ENOTTY;
                        return (error);
                }
                error = 0;
                nmdm_crossover(pti, ourpart, otherpart);
        }
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&tp2->t_token);
+       lwkt_reltoken(&tp->t_token);
+
        return (error);
 }
 
+/*
+ * Caller must hold both tty tokens
+ */
 static void
 nmdm_crossover(struct nm_softc *pti,
                struct softpart *ourpart,
                struct softpart *otherpart)
 {
-       lwkt_gettoken(&tty_token);
        otherpart->modemsignals &= ~(TIOCM_CTS|TIOCM_CAR);
        if (ourpart->modemsignals & TIOCM_RTS)
                otherpart->modemsignals |= TIOCM_CTS;
        if (ourpart->modemsignals & TIOCM_DTR)
                otherpart->modemsignals |= TIOCM_CAR;
-       lwkt_reltoken(&tty_token);
 }
 
 
@@ -595,10 +620,7 @@ static void nmdm_drvinit (void *unused);
 static void
 nmdm_drvinit(void *unused)
 {
-       /* XXX: Gross hack for DEVFS */
-       lwkt_gettoken(&tty_token);
        nmdminit(0);
-       lwkt_reltoken(&tty_token);
 }
 
 SYSINIT(nmdmdev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE + CDEV_MAJOR, nmdm_drvinit,
index 4583ca6..5685644 100644 (file)
@@ -117,6 +117,7 @@ static int snooplinedisc;
 
 
 static LIST_HEAD(, snoop) snp_sclist = LIST_HEAD_INITIALIZER(&snp_sclist);
+static struct lwkt_token  snp_token = LWKT_TOKEN_INITIALIZER(snp_token);
 
 static struct tty      *snpdevtotty (cdev_t dev);
 static int             snp_detach (struct snoop *snp);
@@ -130,15 +131,18 @@ snplclose(struct tty *tp, int flag)
        struct snoop *snp;
        int error;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&snp_token);
        snp = tp->t_sc;
        error = snp_down(snp);
        if (error != 0) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&snp_token);
                return (error);
        }
+       lwkt_gettoken(&tp->t_token);
        error = ttylclose(tp, flag);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+       lwkt_reltoken(&snp_token);
+
        return (error);
 }
 
@@ -151,7 +155,7 @@ snplwrite(struct tty *tp, struct uio *uio, int flag)
        int error, ilen;
        char *ibuf;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        error = 0;
        ibuf = NULL;
        snp = tp->t_sc;
@@ -180,7 +184,7 @@ snplwrite(struct tty *tp, struct uio *uio, int flag)
        }
        if (ibuf != NULL)
                kfree(ibuf, M_SNP);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (error);
 }
 
@@ -207,11 +211,11 @@ snpwrite(struct dev_write_args *ap)
        int error, i, len;
        unsigned char c[SNP_INPUT_BUF];
 
-       lwkt_gettoken(&tty_token);
        snp = dev->si_drv1;
        tp = snp->snp_tty;
+       lwkt_gettoken(&tp->t_token);
        if (tp == NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (EIO);
        }
        if ((tp->t_sc == snp) && (tp->t_state & TS_SNOOP) &&
@@ -219,29 +223,29 @@ snpwrite(struct dev_write_args *ap)
                goto tty_input;
 
        kprintf("Snoop: attempt to write to bad tty.\n");
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (EIO);
 
 tty_input:
        if (!(tp->t_state & TS_ISOPEN)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (EIO);
        }
 
        while (uio->uio_resid > 0) {
                len = (int)szmin(uio->uio_resid, SNP_INPUT_BUF);
                if ((error = uiomove(c, (size_t)len, uio)) != 0) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (error);
                }
                for (i=0; i < len; i++) {
                        if (ttyinput(c[i], tp)) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (EIO);
                        }
                }
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (0);
 }
 
@@ -252,17 +256,19 @@ snpread(struct dev_read_args *ap)
        cdev_t dev = ap->a_head.a_dev;
        struct uio *uio = ap->a_uio;
        struct snoop *snp;
+       struct tty *tp;
        int error, len, n, nblen;
        caddr_t from;
        char *nbuf;
 
-       lwkt_gettoken(&tty_token);
        snp = dev->si_drv1;
+       tp = snp->snp_tty;
+       lwkt_gettoken(&tp->t_token);
        KASSERT(snp->snp_len + snp->snp_base <= snp->snp_blen,
            ("snoop buffer error"));
 
        if (snp->snp_tty == NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (EIO);
        }
 
@@ -271,13 +277,13 @@ snpread(struct dev_read_args *ap)
        do {
                if (snp->snp_len == 0) {
                        if (ap->a_ioflag & IO_NDELAY) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (EWOULDBLOCK);
                        }
                        snp->snp_flags |= SNOOP_RWAIT;
                        error = tsleep((caddr_t)snp, PCATCH, "snprd", 0);
                        if (error != 0) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (error);
                        }
                }
@@ -299,7 +305,6 @@ snpread(struct dev_read_args *ap)
        if ((snp->snp_flags & SNOOP_OFLOW) && (n < snp->snp_len)) {
                snp->snp_flags &= ~SNOOP_OFLOW;
        }
-       crit_enter();
        nblen = snp->snp_blen;
        if (((nblen / 2) >= SNOOP_MINLEN) && (nblen / 2) >= snp->snp_len) {
                while (nblen / 2 >= snp->snp_len && nblen / 2 >= SNOOP_MINLEN)
@@ -312,14 +317,13 @@ snpread(struct dev_read_args *ap)
                        snp->snp_base = 0;
                }
        }
-       crit_exit();
+       lwkt_reltoken(&tp->t_token);
 
-       lwkt_reltoken(&tty_token);
        return (error);
 }
 
 /*
- * NOTE: Must be called with tty_token held
+ * NOTE: Must be called with tp->t_token held
  */
 static int
 snp_in(struct snoop *snp, char *buf, int n)
@@ -329,7 +333,6 @@ snp_in(struct snoop *snp, char *buf, int n)
        caddr_t from, to;
        char *nbuf;
 
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
        KASSERT(n >= 0, ("negative snoop char count"));
 
        if (n == 0)
@@ -356,7 +359,6 @@ snp_in(struct snoop *snp, char *buf, int n)
 
 
        if (n > s_free) {
-               crit_enter();
                nblen = snp->snp_blen;
                while ((n > s_free) && ((nblen * 2) <= SNOOP_MAXLEN)) {
                        nblen = snp->snp_blen * 2;
@@ -374,10 +376,8 @@ snp_in(struct snoop *snp, char *buf, int n)
                                snp->snp_flags &= ~SNOOP_RWAIT;
                                wakeup((caddr_t)snp);
                        }
-                       crit_exit();
                        return (0);
                }
-               crit_exit();
        }
        if (n > s_tail) {
                from = (caddr_t)(snp->snp_buf + snp->snp_base);
@@ -405,16 +405,16 @@ snpopen(struct dev_open_args *ap)
        cdev_t dev = ap->a_head.a_dev;
        struct snoop *snp;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&snp_token);
        if (dev->si_drv1 == NULL) {
 #if 0
                make_dev(&snp_ops, minor(dev), UID_ROOT, GID_WHEEL,
                    0600, "snp%d", minor(dev));
 #endif
                dev->si_drv1 = snp = kmalloc(sizeof(*snp), M_SNP,
-                   M_WAITOK | M_ZERO);
+                                            M_WAITOK | M_ZERO);
        } else {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&snp_token);
                return (EBUSY);
        }
 
@@ -436,19 +436,19 @@ snpopen(struct dev_open_args *ap)
        snp->snp_target = NULL;
 
        LIST_INSERT_HEAD(&snp_sclist, snp, snp_list);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&snp_token);
        return (0);
 }
 
 /*
- * NOTE: Must be called with tty_token held
+ * NOTE: Must be called with snp_token held
  */
 static int
 snp_detach(struct snoop *snp)
 {
        struct tty *tp;
 
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
+       ASSERT_LWKT_TOKEN_HELD(&snp_token);
        snp->snp_base = 0;
        snp->snp_len = 0;
 
@@ -460,13 +460,16 @@ snp_detach(struct snoop *snp)
        if (tp == NULL)
                goto detach_notty;
 
-       if (tp && (tp->t_sc == snp) && (tp->t_state & TS_SNOOP) &&
+       lwkt_gettoken(&tp->t_token);
+       if ((tp->t_sc == snp) && (tp->t_state & TS_SNOOP) &&
            tp->t_line == snooplinedisc) {
                tp->t_sc = NULL;
                tp->t_state &= ~TS_SNOOP;
                tp->t_line = snp->snp_olddisc;
-       } else
+       } else {
                kprintf("Snoop: bad attached tty data.\n");
+       }
+       lwkt_reltoken(&tp->t_token);
 
        snp->snp_tty = NULL;
        snp->snp_target = NULL;
@@ -486,7 +489,7 @@ snpclose(struct dev_close_args *ap)
        struct snoop *snp;
        int ret;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&snp_token);
        snp = dev->si_drv1;
        snp->snp_blen = 0;
        LIST_REMOVE(snp, snp_list);
@@ -498,18 +501,17 @@ snpclose(struct dev_close_args *ap)
                destroy_dev(dev);
        }
        ret = snp_detach(snp);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&snp_token);
        return ret;
 }
 
 /*
- * NOTE: Must be called with tty_token held
+ * NOTE: Must be called with snp_token held
  */
 static int
 snp_down(struct snoop *snp)
 {
-
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
+       ASSERT_LWKT_TOKEN_HELD(&snp_token);
        if (snp->snp_blen != SNOOP_MINLEN) {
                kfree(snp->snp_buf, M_SNP);
                snp->snp_buf = kmalloc(SNOOP_MINLEN, M_SNP, M_WAITOK);
@@ -529,29 +531,30 @@ snpioctl(struct dev_ioctl_args *ap)
        cdev_t tdev;
        int ret;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&snp_token);
        snp = dev->si_drv1;
+
        switch (ap->a_cmd) {
        case SNPSTTY:
                tdev = udev2dev(*((udev_t *)ap->a_data), 0);
                if (tdev == NULL) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&snp_token);
                        ret = snp_down(snp);
                        return ret;
                }
 
                tp = snpdevtotty(tdev);
                if (!tp) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&snp_token);
                        return (EINVAL);
                }
+               lwkt_gettoken(&tp->t_token);
                if (tp->t_state & TS_SNOOP) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
+                       lwkt_reltoken(&snp_token);
                        return (EBUSY);
                }
 
-               crit_enter();
-
                if (snp->snp_target == NULL) {
                        tpo = snp->snp_tty;
                        if (tpo)
@@ -571,7 +574,7 @@ snpioctl(struct dev_ioctl_args *ap)
                 */
                snp->snp_flags &= ~SNOOP_OFLOW;
                snp->snp_flags &= ~SNOOP_DOWN;
-               crit_exit();
+               lwkt_reltoken(&tp->t_token);
                break;
 
        case SNPGTTY:
@@ -591,10 +594,9 @@ snpioctl(struct dev_ioctl_args *ap)
                break;
 
        case FIONREAD:
-               crit_enter();
-               if (snp->snp_tty != NULL)
+               if (snp->snp_tty != NULL) {
                        *(int *)ap->a_data = snp->snp_len;
-               else
+               } else {
                        if (snp->snp_flags & SNOOP_DOWN) {
                                if (snp->snp_flags & SNOOP_OFLOW)
                                        *(int *)ap->a_data = SNP_OFLOW;
@@ -603,14 +605,15 @@ snpioctl(struct dev_ioctl_args *ap)
                        } else {
                                *(int *)ap->a_data = SNP_DETACH;
                        }
-               crit_exit();
+               }
                break;
 
        default:
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&snp_token);
                return (ENOTTY);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&snp_token);
+
        return (0);
 }
 
@@ -626,8 +629,9 @@ snpkqfilter(struct dev_kqfilter_args *ap)
        struct snoop *snp = dev->si_drv1;
        struct knote *kn = ap->a_kn;
        struct klist *klist;
+       struct tty *tp = snp->snp_tty;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        ap->a_result = 0;
 
        switch (kn->kn_filter) {
@@ -641,14 +645,14 @@ snpkqfilter(struct dev_kqfilter_args *ap)
                break;
        default:
                ap->a_result = EOPNOTSUPP;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (0);
        }
 
        klist = &snp->snp_kq.ki_note;
        knote_insert(klist, kn);
+       lwkt_reltoken(&tp->t_token);
 
-       lwkt_reltoken(&tty_token);
        return (0);
 }
 
@@ -666,9 +670,10 @@ static int
 snpfilter_rd(struct knote *kn, long hint)
 {
        struct snoop *snp = (struct snoop *)kn->kn_hook;
+       struct tty *tp = snp->snp_tty;
        int ready = 0;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        /*
         * If snoop is down, we don't want to poll forever so we return 1.
         * Caller should see if we down via FIONREAD ioctl().  The last should
@@ -676,8 +681,8 @@ snpfilter_rd(struct knote *kn, long hint)
         */
        if (snp->snp_flags & SNOOP_DOWN || snp->snp_len > 0)
                ready = 1;
+       lwkt_reltoken(&tp->t_token);
 
-       lwkt_reltoken(&tty_token);
        return (ready);
 }
 
@@ -692,11 +697,13 @@ static int
 snpclone(struct dev_clone_args *ap)
 {
        int unit;
-       lwkt_gettoken(&tty_token);
+
+       lwkt_gettoken(&snp_token);
        unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(snp), 0);
        ap->a_dev = make_only_dev(&snp_ops, unit, UID_ROOT, GID_WHEEL, 0600,
-                                                       "snp%d", unit);
-       lwkt_reltoken(&tty_token);
+                                 "snp%d", unit);
+       lwkt_reltoken(&snp_token);
+
        return 0;
 }
 
@@ -705,7 +712,8 @@ snp_modevent(module_t mod, int type, void *data)
 {
        int i;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&snp_token);
+
        switch (type) {
        case MOD_LOAD:
                snooplinedisc = ldisc_register(LDISC_LOAD, &snpdisc);
@@ -719,7 +727,7 @@ snp_modevent(module_t mod, int type, void *data)
                break;
        case MOD_UNLOAD:
                if (!LIST_EMPTY(&snp_sclist)) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&snp_token);
                        return (EBUSY);
                }
                ldisc_deregister(snooplinedisc);
@@ -730,7 +738,8 @@ snp_modevent(module_t mod, int type, void *data)
        default:
                break;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&snp_token);
+
        return (0);
 }
 
index 0e480dc..3510bd9 100644 (file)
@@ -557,7 +557,7 @@ vga_pxlborder_planar(scr_stat *scp, int color)
        int y;
        int i;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
 
        (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
 
@@ -585,7 +585,7 @@ vga_pxlborder_planar(scr_stat *scp, int color)
        }
        outw(GDCIDX, 0x0000);           /* set/reset */
        outw(GDCIDX, 0x0001);           /* set/reset enable */
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
 }
 
 static void
@@ -1230,9 +1230,9 @@ vga_pxlmouse_planar(scr_stat *scp, int x, int y, int on)
 static void
 vga_grborder(scr_stat *scp, int color)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
 }
 
 #endif
index 20afae9..fcc26d0 100644 (file)
@@ -61,12 +61,11 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
     int new_ysize;
     int error;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, mode, &info)) {
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ENODEV;
     }
-    lwkt_reltoken(&tty_token);
 
     /* adjust argument values */
     if (fontsize <= 0)
@@ -105,20 +104,19 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
        ysize = info.vi_height;
 
     /* stop screen saver, etc */
-    crit_enter();
     if ((error = sc_clean_up(scp, FALSE))) {
-       crit_exit();
+       lwkt_reltoken(&vga_token);
        return error;
     }
 
     if (scp->sc->fbi != NULL &&
        sc_render_match(scp, "kms", V_INFO_MM_TEXT) == NULL) {
-       crit_exit();
+       lwkt_reltoken(&vga_token);
        return ENODEV;
     }
     if (scp->sc->fbi == NULL &&
        sc_render_match(scp, scp->sc->adp->va_name, V_INFO_MM_TEXT) == NULL) {
-       crit_exit();
+       lwkt_reltoken(&vga_token);
        return ENODEV;
     }
 
@@ -158,22 +156,23 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
 #ifndef SC_NO_HISTORY
     sc_alloc_history_buffer(scp, new_ysize, prev_ysize, FALSE);
 #endif
-    crit_exit();
 
     if (scp == scp->sc->cur_scp)
        set_mode(scp);
     scp->status &= ~UNKNOWN_MODE;
 
-    if (tp == NULL)
-       return 0;
-    DPRINTF(5, ("ws_*size (%d,%d), size (%d,%d)\n",
-       tp->t_winsize.ws_col, tp->t_winsize.ws_row, scp->xsize, scp->ysize));
-    if (tp->t_winsize.ws_col != scp->xsize
-       || tp->t_winsize.ws_row != scp->ysize) {
-       tp->t_winsize.ws_col = scp->xsize;
-       tp->t_winsize.ws_row = scp->ysize;
-       pgsignal(tp->t_pgrp, SIGWINCH, 1);
+    if (tp) {
+       DPRINTF(5, ("ws_*size (%d,%d), size (%d,%d)\n",
+               tp->t_winsize.ws_col, tp->t_winsize.ws_row,
+               scp->xsize, scp->ysize));
+       if (tp->t_winsize.ws_col != scp->xsize ||
+           tp->t_winsize.ws_row != scp->ysize) {
+           tp->t_winsize.ws_col = scp->xsize;
+           tp->t_winsize.ws_row = scp->ysize;
+           pgsignal(tp->t_pgrp, SIGWINCH, 1);
+       }
     }
+    lwkt_reltoken(&vga_token);
 
     return 0;
 }
@@ -187,12 +186,12 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
     video_info_t info;
     int error;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, mode, &info)) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return ENODEV;
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 
     /* stop screen saver, etc */
     crit_enter();
@@ -241,13 +240,13 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
     refresh_ega_palette(scp);
     scp->status &= ~UNKNOWN_MODE;
 
-    if (tp == NULL)
-       return 0;
-    if (tp->t_winsize.ws_xpixel != scp->xpixel
-       || tp->t_winsize.ws_ypixel != scp->ypixel) {
-       tp->t_winsize.ws_xpixel = scp->xpixel;
-       tp->t_winsize.ws_ypixel = scp->ypixel;
-       pgsignal(tp->t_pgrp, SIGWINCH, 1);
+    if (tp) {
+       if (tp->t_winsize.ws_xpixel != scp->xpixel ||
+           tp->t_winsize.ws_ypixel != scp->ypixel) {
+           tp->t_winsize.ws_xpixel = scp->xpixel;
+           tp->t_winsize.ws_ypixel = scp->ypixel;
+           pgsignal(tp->t_pgrp, SIGWINCH, 1);
+       }
     }
 
     return 0;
@@ -267,12 +266,12 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
     int new_ysize;
     int error;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, scp->mode, &info)) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return ENODEV;          /* this shouldn't happen */
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 
     /* adjust argument values */
     if (fontsize <= 0)
@@ -400,13 +399,13 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
 
     scp->status &= ~UNKNOWN_MODE;
 
-    if (tp == NULL)
-       return 0;
-    if (tp->t_winsize.ws_col != scp->xsize
-       || tp->t_winsize.ws_row != scp->ysize) {
-       tp->t_winsize.ws_col = scp->xsize;
-       tp->t_winsize.ws_row = scp->ysize;
-       pgsignal(tp->t_pgrp, SIGWINCH, 1);
+    if (tp) {
+       if (tp->t_winsize.ws_col != scp->xsize ||
+           tp->t_winsize.ws_row != scp->ysize) {
+           tp->t_winsize.ws_col = scp->xsize;
+           tp->t_winsize.ws_row = scp->ysize;
+           pgsignal(tp->t_pgrp, SIGWINCH, 1);
+       }
     }
 
     return 0;
@@ -436,7 +435,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
     if (adp == NULL && scp->sc->fbi == NULL)   /* shouldn't happen??? */
        return ENODEV;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     switch (cmd) {
 
     case CONS_CURRENTADP:      /* get current adapter index */
@@ -446,7 +445,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
        } else {
            ret = fb_ioctl(adp, FBIO_ADAPTER, data);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ret;
 
     case CONS_CURRENT:         /* get current adapter type */
@@ -456,57 +455,57 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
        } else {
            ret = fb_ioctl(adp, FBIO_ADPTYPE, data);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ret;
 
     case CONS_ADPINFO:         /* adapter information */
     case FBIO_ADPINFO:
        if (scp->sc->fbi != NULL) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENODEV;
        }
        if (((video_adapter_info_t *)data)->va_index >= 0) {
            adp = vid_get_adapter(((video_adapter_info_t *)data)->va_index);
            if (adp == NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return ENODEV;
            }
        }
        ret = fb_ioctl(adp, FBIO_ADPINFO, data);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ret;
 
     case CONS_GET:             /* get current video mode */
     case FBIO_GETMODE:
        *(int *)data = scp->mode;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
 #ifndef SC_NO_MODE_CHANGE
     case CONS_SET:
     case FBIO_SETMODE:         /* set video mode */
        if (scp->sc->fbi != NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                if (*(int *)data != 0)
                        return ENODEV;
                else
                        return 0;
        }
        if (!(adp->va_flags & V_ADP_MODECHANGE)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENODEV;
        }
        info.vi_mode = *(int *)data;
        error = fb_ioctl(adp, FBIO_MODEINFO, &info);
        if (error) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return error;
        }
        if (info.vi_flags & V_INFO_GRAPHICS) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return sc_set_graphics_mode(scp, tp, *(int *)data);
        } else {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return sc_set_text_mode(scp, tp, *(int *)data, 0, 0, 0);
        }
 #endif /* SC_NO_MODE_CHANGE */
@@ -531,7 +530,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
        } else {
            ret = fb_ioctl(adp, FBIO_MODEINFO, data);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ret;
 
     case CONS_FINDMODE:                /* find a matching video mode */
@@ -541,26 +540,26 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
        } else {
            ret = fb_ioctl(adp, FBIO_FINDMODE, data);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ret;
 
     case CONS_SETWINORG:       /* set frame buffer window origin */
     case FBIO_SETWINORG:
        if (scp != scp->sc->cur_scp) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENODEV;      /* XXX */
        }
        if (scp->sc->fbi != NULL) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENODEV;
        }
        ret = fb_ioctl(adp, FBIO_SETWINORG, data);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ret;
 
     case FBIO_GETWINORG:       /* get frame buffer window origin */
        if (scp != scp->sc->cur_scp) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENODEV;      /* XXX */
        }
        if (scp->sc->fbi != NULL) {
@@ -568,7 +567,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
        } else {
            ret = fb_ioctl(adp, FBIO_GETWINORG, data);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ret;
 
     case FBIO_GETDISPSTART:
@@ -576,7 +575,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
     case FBIO_GETLINEWIDTH:
     case FBIO_SETLINEWIDTH:
        if (scp != scp->sc->cur_scp) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENODEV;      /* XXX */
        }
        if (scp->sc->fbi != NULL) {
@@ -589,12 +588,12 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
        } else {
            ret = fb_ioctl(adp, cmd, data);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ret;
 
     case FBIO_BLANK:
        if (scp != scp->sc->cur_scp) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENODEV;
        }
        if (scp->sc->fbi != NULL && ISGRAPHSC(scp)) {
@@ -606,7 +605,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
        } else {
            ret = ENODEV;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ret;
 
     case FBIO_GETPALETTE:
@@ -623,7 +622,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
     case FBIOGCURPOS:
     case FBIOGCURMAX:
        if (scp != scp->sc->cur_scp) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENODEV;      /* XXX */
        }
        if (scp->sc->fbi != NULL) {
@@ -642,7 +641,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
        } else {
            ret = fb_ioctl(adp, cmd, data);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ret;
 
     case KDSETMODE:            /* set current mode of this (virtual) console */
@@ -653,7 +652,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
             * text mode to switch back to...
             */
            if (scp->status & GRAPHICS_MODE) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return EINVAL;
            }
            /* restore fonts & palette ! */
@@ -689,13 +688,13 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
             * text/pixel mode to switch back to...
             */
            if (scp->status & GRAPHICS_MODE) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return EINVAL;
            }
            crit_enter();
            if ((error = sc_clean_up(scp, FALSE))) {
                crit_exit();
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return error;
            }
            scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN;
@@ -705,28 +704,28 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
                set_mode(scp);
            sc_clear_screen(scp);
            scp->status &= ~UNKNOWN_MODE;
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return 0;
 
 #ifdef SC_PIXEL_MODE
        case KD_PIXEL:          /* pixel (raster) display */
            if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return EINVAL;
             }
            if (scp->sc->fbi != NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return ENODEV;
            }
            if (scp->status & GRAPHICS_MODE) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize, 
                                         scp->font_height);
            }
            crit_enter();
            if ((error = sc_clean_up(scp, FALSE))) {
                crit_exit();
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return error;
            }
            scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
@@ -737,7 +736,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
            }
            sc_clear_screen(scp);
            scp->status &= ~UNKNOWN_MODE;
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return 0;
 #endif /* SC_PIXEL_MODE */
 
@@ -745,16 +744,16 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
            crit_enter();
            if ((error = sc_clean_up(scp, FALSE))) {
                crit_exit();
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return error;
            }
            scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN;
            crit_exit();
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return 0;
 
        default:
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EINVAL;
        }
        /* NOT REACHED */
@@ -762,10 +761,10 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
 #ifdef SC_PIXEL_MODE
     case KDRASTER:             /* set pixel (raster) display mode */
        if (scp->sc->fbi != NULL || ISUNKNOWNSC(scp) || ISTEXTSC(scp)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENODEV;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1], 
                                 ((int *)data)[2]);
 #endif /* SC_PIXEL_MODE */
@@ -776,23 +775,23 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
         * as KD_TEXT... 
         */
        *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case KDSBORDER:            /* set border color of this (virtual) console */
        /* Only values in the range [0..15] allowed */
        if (*(int *)data < 0 || *(int *)data > 15) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return EINVAL;
        }
        scp->border = *(int *)data;
        if (scp == scp->sc->cur_scp)
            sc_set_border(scp, scp->border);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
     }
 
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return ENOIOCTL;
 }
 
index 2dbd7f0..4d1f6e4 100644 (file)
@@ -328,10 +328,10 @@ register_framebuffer(struct fb_info *info)
        if (!info->is_vga_boot_display)
                return 0;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        sc = sc_get_softc(0, (sc_console_unit == 0) ? SC_KERNEL_CONSOLE : 0);
        if (sc == NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                kprintf("%s: sc_get_softc(%d, %d) returned NULL\n", __func__,
                    0, (sc_console_unit == 0) ? SC_KERNEL_CONSOLE : 0);
                return 0;
@@ -340,7 +340,7 @@ register_framebuffer(struct fb_info *info)
        /* Ignore this framebuffer if we already switched to KMS framebuffer */
        if (sc->fbi != NULL && sc->fbi != &efi_fb_info &&
            sc->fbi != sc->dummy_fb_info) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return 0;
        }
 
@@ -386,7 +386,7 @@ register_framebuffer(struct fb_info *info)
 #endif /* NSPLASH */
 
        lockmgr(&sc_asynctd_lk, LK_RELEASE);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 }
 
@@ -395,17 +395,17 @@ unregister_framebuffer(struct fb_info *info)
 {
        sc_softc_t *sc;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        sc = sc_get_softc(0, (sc_console_unit == 0) ? SC_KERNEL_CONSOLE : 0);
        if (sc == NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                kprintf("%s: sc_get_softc(%d, %d) returned NULL\n", __func__,
                    0, (sc_console_unit == 0) ? SC_KERNEL_CONSOLE : 0);
                return;
        }
 
        if (sc->fbi != info) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return;
        }
 
@@ -447,7 +447,7 @@ unregister_framebuffer(struct fb_info *info)
        syscons_unlock();
        lockmgr(&sc_asynctd_lk, LK_RELEASE);
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
 }
 
 void
@@ -583,7 +583,7 @@ sc_attach_unit(int unit, int flags)
        sc->dev[0] = make_dev(&sc_ops, sc_console_unit*MAXCONS, UID_ROOT,
                              GID_WHEEL, 0600, "ttyv%s", makedev_unit_b32(tbuf,
                              sc_console_unit * MAXCONS));
-       sc->dev[0]->si_tty = ttymalloc(sc->dev[0]->si_tty);
+       ttymalloc(&sc->dev[0]->si_tty);
        sc->dev[0]->si_drv1 = sc_console;
     }
 
@@ -642,7 +642,7 @@ sc_attach_unit(int unit, int flags)
     }
     cctl_dev = make_dev(&sc_ops, SC_CONSOLECTL,
                        UID_ROOT, GID_WHEEL, 0600, "consolectl");
-    cctl_dev->si_tty = sc_console_tty = ttymalloc(sc_console_tty);
+    cctl_dev->si_tty = ttymalloc(&sc_console_tty);
     cctl_dev->si_drv1 = sc_console;
     return 0;
 }
@@ -707,18 +707,19 @@ scopen(struct dev_open_args *ap)
     keyarg_t key;
     int error;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     unit = scdevtounit(dev);
     DPRINTF(5, ("scopen: dev:%d,%d, unit:%d, vty:%d\n",
                major(dev), minor(dev), unit, SC_VTY(dev)));
 
     sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
     if (sc == NULL) {
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ENXIO;
     }
 
-    tp = dev->si_tty = ttymalloc(dev->si_tty);
+    tp = ttymalloc(&dev->si_tty);
+    lwkt_gettoken(&tp->t_token);
     tp->t_oproc = scstart;
     tp->t_param = scparam;
     tp->t_stop = nottystop;
@@ -744,7 +745,8 @@ scopen(struct dev_open_args *ap)
     }
     else
        if (tp->t_state & TS_XCLUDE && priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&tp->t_token);
+           lwkt_reltoken(&vga_token);
            return(EBUSY);
        }
 
@@ -772,7 +774,9 @@ scopen(struct dev_open_args *ap)
            lwkt_create(scrn_update_thread, scp, &scp->asynctd, NULL, 0, -1,
                        "syscons%d", SC_VTY(dev));
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&tp->t_token);
+    lwkt_reltoken(&vga_token);
+
     return error;
 }
 
@@ -783,7 +787,8 @@ scclose(struct dev_close_args *ap)
     struct tty *tp = dev->si_tty;
     scr_stat *scp;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
+    lwkt_gettoken(&tp->t_token);
     if (SC_VTY(dev) != SC_CONSOLECTL) {
        scp = SC_STAT(tp->t_dev);
        /* were we in the middle of the VT switching process? */
@@ -823,7 +828,8 @@ scclose(struct dev_close_args *ap)
     }
     (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
     ttyclose(tp);
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&tp->t_token);
+    lwkt_reltoken(&vga_token);
 
     return(0);
 }
@@ -833,10 +839,10 @@ scread(struct dev_read_args *ap)
 {
     int ret;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     sc_touch_scrn_saver();
     ret = ttyread(ap);
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return ret;
 }
 
@@ -849,7 +855,7 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
     size_t len;
     u_char *cp;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     /*
      * WARNING: In early boot sc->dev may not be setup yet.
      */
@@ -859,7 +865,7 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
     switch (event) {
     case KBDIO_KEYINPUT:
        if (sc->kbd && sc->kbd->kb_flags & KB_POLLED) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return 0;
        }
        break;
@@ -869,10 +875,10 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
        sc->keyboard = -1;
        syscons_unlock();
        kbd_release(thiskbd, (void *)&sc->keyboard);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
     default:
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return EINVAL;
     }
 
@@ -896,6 +902,8 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
        }
        syscons_unlock();
 
+       lwkt_gettoken(&cur_tty->t_token);
+
        switch (KEYFLAGS(c)) {
        case 0x0000: /* normal key */
            (*linesw[cur_tty->t_line].l_rint)(KEYCHAR(c), cur_tty);
@@ -917,24 +925,26 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
            (*linesw[cur_tty->t_line].l_rint)('Z', cur_tty);
            break;
        }
+       lwkt_reltoken(&cur_tty->t_token);
     }
 
     syscons_lock();
     sc->cur_scp->status |= MOUSE_HIDDEN;
     syscons_unlock();
 
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return 0;
 }
 
 static int
 scparam(struct tty *tp, struct termios *t)
 {
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&tp->t_token);
     tp->t_ispeed = t->c_ispeed;
     tp->t_ospeed = t->c_ospeed;
     tp->t_cflag = t->c_cflag;
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&tp->t_token);
+
     return 0;
 }
 
@@ -951,19 +961,19 @@ scioctl(struct dev_ioctl_args *ap)
     sc_softc_t *sc;
     scr_stat *scp;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     tp = dev->si_tty;
 
     error = sc_vid_ioctl(tp, cmd, data, flag);
     if (error != ENOIOCTL) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return error;
     }
 
 #ifndef SC_NO_HISTORY
     error = sc_hist_ioctl(tp, cmd, data, flag);
     if (error != ENOIOCTL) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return error;
     }
 #endif
@@ -971,7 +981,7 @@ scioctl(struct dev_ioctl_args *ap)
 #ifndef SC_NO_SYSMOUSE
     error = sc_mouse_ioctl(tp, cmd, data, flag);
     if (error != ENOIOCTL) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return error;
     }
 #endif
@@ -986,7 +996,7 @@ scioctl(struct dev_ioctl_args *ap)
        error = (*scp->tsw->te_ioctl)(scp, tp, cmd, data, flag);
        syscons_unlock();
        if (error != ENOIOCTL) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return error;
        }
     }
@@ -995,7 +1005,7 @@ scioctl(struct dev_ioctl_args *ap)
 
     case GIO_ATTR:             /* get current attributes */
        /* this ioctl is not processed here, but in the terminal emulator */
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ENOTTY;
 
     case GIO_COLOR:            /* is this a color console ? */
@@ -1003,19 +1013,19 @@ scioctl(struct dev_ioctl_args *ap)
            *(int *)data = 1;
        else
            *(int *)data = (sc->adp->va_flags & V_ADP_COLOR) ? 1 : 0;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case CONS_BLANKTIME:       /* set screen saver timeout (0 = no saver) */
        if (*(int *)data < 0 || *(int *)data > MAX_BLANKTIME) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
             return EINVAL;
        }
        syscons_lock();
        scrn_blank_time = *(int *)data;
        run_scrn_saver = (scrn_blank_time != 0);
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case CONS_CURSORTYPE:      /* set cursor type blink/noblink */
@@ -1039,7 +1049,7 @@ scioctl(struct dev_ioctl_args *ap)
            sc_draw_cursor_image(sc->cur_scp);
        }
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case CONS_BELLTYPE:        /* set bell type sound/visual */
@@ -1056,7 +1066,7 @@ scioctl(struct dev_ioctl_args *ap)
            sc->flags &= ~SC_QUIET_BELL;
 
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case CONS_GETINFO:         /* get current (virtual) console info */
@@ -1083,16 +1093,16 @@ scioctl(struct dev_ioctl_args *ap)
            if (scp == sc->cur_scp)
                save_kbd_state(scp, FALSE);
            ptr->mk_keylock = scp->status & LOCK_MASK;
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return 0;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return EINVAL;
     }
 
     case CONS_GETVERS:         /* get version number */
        *(int*)data = 0x200;    /* version 2.0 */
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case CONS_IDLE:            /* see if the screen has been idle */
@@ -1108,7 +1118,7 @@ scioctl(struct dev_ioctl_args *ap)
        *(int *)data = (sc->flags & SC_SCRN_IDLE)
                       && (!ISGRAPHSC(sc->cur_scp)
                           || (sc->cur_scp->status & SAVER_RUNNING));
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case CONS_SAVERMODE:       /* set saver mode */
@@ -1122,7 +1132,7 @@ scioctl(struct dev_ioctl_args *ap)
 #if NSPLASH > 0
            if ((error = wait_scrn_saver_stop(NULL, TRUE))) {
                syscons_unlock();
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return error;
            }
 #endif /* NSPLASH */
@@ -1142,10 +1152,10 @@ scioctl(struct dev_ioctl_args *ap)
            syscons_unlock();
            break;
        default:
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EINVAL;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case CONS_SAVERSTART:      /* immediately start/stop the screen saver */
@@ -1158,7 +1168,7 @@ scioctl(struct dev_ioctl_args *ap)
        if (run_scrn_saver)
            sc->scrn_time_stamp -= scrn_blank_time;
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case CONS_SCRSHOT:         /* get a screen shot */
@@ -1167,18 +1177,18 @@ scioctl(struct dev_ioctl_args *ap)
        syscons_lock();
        if (ISGRAPHSC(scp)) {
            syscons_unlock();
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EOPNOTSUPP;
        }
        if (scp->xsize != ptr->xsize || scp->ysize != ptr->ysize) {
            syscons_unlock();
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EINVAL;
        }
        syscons_unlock();
        copyout ((void*)scp->vtb.vtb_buffer, ptr->buf,
                 ptr->xsize * ptr->ysize * sizeof(uint16_t));
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
     }
 
@@ -1191,7 +1201,7 @@ scioctl(struct dev_ioctl_args *ap)
        if (scp->smode.mode == VT_PROCESS) {
            if (scp->proc == pfindn(scp->pid) && scp->proc != curproc) {
                DPRINTF(5, ("error EPERM\n"));
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return EPERM;
            }
        }
@@ -1214,7 +1224,7 @@ scioctl(struct dev_ioctl_args *ap)
                || !ISSIGVALID(mode->frsig)) {
                syscons_unlock();
                DPRINTF(5, ("error EINVAL\n"));
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return EINVAL;
            }
            DPRINTF(5, ("VT_PROCESS %d, ", curproc->p_pid));
@@ -1226,13 +1236,13 @@ scioctl(struct dev_ioctl_args *ap)
        }
        syscons_unlock();
        DPRINTF(5, ("\n"));
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
     }
 
     case VT_GETMODE:           /* get screen switcher mode */
        bcopy(&scp->smode, data, sizeof(struct vt_mode));
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case VT_RELDISP:           /* screen switcher ioctl */
@@ -1243,13 +1253,13 @@ scioctl(struct dev_ioctl_args *ap)
        syscons_lock();
        if ((scp != sc->cur_scp) || (scp->smode.mode != VT_PROCESS)) {
            syscons_unlock();
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EINVAL;
        }
        /* ...and this process is controlling it. */
        if (scp->proc != curproc) {
            syscons_unlock();
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EPERM;
        }
        error = EINVAL;
@@ -1267,7 +1277,7 @@ scioctl(struct dev_ioctl_args *ap)
                DPRINTF(5, ("sc%d: VT_ACKACQ\n", sc->unit));
            syscons_unlock();
            /* Wait for drm modesetting callback to finish. */
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            if (sc->fb_set_par_task != NULL)
                taskqueue_drain(taskqueue_thread[0], sc->fb_set_par_task);
            return error;
@@ -1275,7 +1285,7 @@ scioctl(struct dev_ioctl_args *ap)
            break;
        }
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 
     case VT_OPENQRY:           /* return free virtual console */
@@ -1283,11 +1293,11 @@ scioctl(struct dev_ioctl_args *ap)
            tp = VIRTUAL_TTY(sc, i);
            if (!ISTTYOPEN(tp)) {
                *(int *)data = i + 1;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return 0;
            }
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return EINVAL;
 
     case VT_ACTIVATE:          /* switch to screen *data */
@@ -1296,20 +1306,20 @@ scioctl(struct dev_ioctl_args *ap)
        sc_clean_up(sc->cur_scp, TRUE);
        error = sc_switch_scr(sc, i);
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 
     case VT_WAITACTIVE:        /* wait for switch to occur */
        i = (*(int *)data == 0) ? scp->index : (*(int *)data - 1);
        if ((i < sc->first_vty) || (i >= sc->first_vty + sc->vtys)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EINVAL;
        }
        syscons_lock();
        error = sc_clean_up(sc->cur_scp, TRUE);
        syscons_unlock();
        if (error) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return error;
        }
 
@@ -1320,12 +1330,12 @@ scioctl(struct dev_ioctl_args *ap)
         */
        scp = SC_STAT(SC_DEV(sc, i));
        if (scp == NULL || scp == scp->sc->cur_scp) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return 0;
        }
        error = tsleep((caddr_t)&scp->smode, PCATCH, "waitvt", 0);
        /* May return ERESTART */
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        /* Wait for drm modesetting callback to finish. */
        if (sc->fb_set_par_task != NULL)
            taskqueue_drain(taskqueue_thread[0], sc->fb_set_par_task);
@@ -1333,12 +1343,12 @@ scioctl(struct dev_ioctl_args *ap)
 
     case VT_GETACTIVE:         /* get active vty # */
        *(int *)data = sc->cur_scp->index + 1;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case VT_GETINDEX:          /* get this vty # */
        *(int *)data = scp->index + 1;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case VT_LOCKSWITCH:                /* prevent vty switching */
@@ -1348,17 +1358,17 @@ scioctl(struct dev_ioctl_args *ap)
        else
            sc->flags &= ~SC_SCRN_VTYLOCK;
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case KDENABIO:             /* allow io operations */
        error = priv_check_cred(ap->a_cred, PRIV_ROOT, 0);
        if (error != 0) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return error;
        }
        if (securelevel > 0) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EPERM;
        }
 #if defined(__i386__)
@@ -1366,7 +1376,7 @@ scioctl(struct dev_ioctl_args *ap)
 #elif defined(__x86_64__)
        curthread->td_lwp->lwp_md.md_regs->tf_rflags |= PSL_IOPL;
 #endif
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case KDDISABIO:            /* disallow io operations (default) */
@@ -1375,12 +1385,12 @@ scioctl(struct dev_ioctl_args *ap)
 #elif defined(__x86_64__)
        curthread->td_lwp->lwp_md.md_regs->tf_rflags &= ~PSL_IOPL;
 #endif
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return 0;
 
     case KDSKBSTATE:           /* set keyboard state (locks) */
        if (*(int *)data & ~LOCK_MASK) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EINVAL;
        }
        syscons_lock();
@@ -1389,14 +1399,14 @@ scioctl(struct dev_ioctl_args *ap)
        syscons_unlock();
        if (scp == sc->cur_scp)
            update_kbd_state(scp, scp->status, LOCK_MASK, FALSE);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case KDGKBSTATE:           /* get keyboard state (locks) */
        if (scp == sc->cur_scp)
            save_kbd_state(scp, FALSE);
        *(int *)data = scp->status & LOCK_MASK;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case KDGETREPEAT:          /* get keyboard repeat & delay rates */
@@ -1404,7 +1414,7 @@ scioctl(struct dev_ioctl_args *ap)
        error = kbd_ioctl(sc->kbd, cmd, data);
        if (error == ENOIOCTL)
            error = ENODEV;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 
     case KDSKBMODE:            /* set keyboard mode */
@@ -1415,24 +1425,24 @@ scioctl(struct dev_ioctl_args *ap)
            scp->kbd_mode = *(int *)data;
            if (scp == sc->cur_scp)
                kbd_ioctl(sc->kbd, cmd, data);
-            lwkt_reltoken(&tty_token);
+            lwkt_reltoken(&vga_token);
            return 0;
        default:
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EINVAL;
        }
        /* NOT REACHED */
 
     case KDGKBMODE:            /* get keyboard mode */
        *(int *)data = scp->kbd_mode;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case KDGKBINFO:
        error = kbd_ioctl(sc->kbd, cmd, data);
        if (error == ENOIOCTL)
            error = ENODEV;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 
     case KDMKTONE:             /* sound the bell */
@@ -1443,7 +1453,7 @@ scioctl(struct dev_ioctl_args *ap)
        else
            sc_bell(scp, scp->bell_pitch, scp->bell_duration);
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case KIOCSOUND:            /* make tone (*data) hz */
@@ -1458,7 +1468,7 @@ scioctl(struct dev_ioctl_args *ap)
            error = 0;
        }
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 
     case KDGKBTYPE:            /* get keyboard type */
@@ -1467,12 +1477,12 @@ scioctl(struct dev_ioctl_args *ap)
            /* always return something? XXX */
            *(int *)data = 0;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case KDSETLED:             /* set keyboard LED status */
        if (*(int *)data & ~LED_MASK) { /* FIXME: LOCK_MASK? */
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EINVAL;
        }
        syscons_lock();
@@ -1481,14 +1491,14 @@ scioctl(struct dev_ioctl_args *ap)
        syscons_unlock();
        if (scp == sc->cur_scp)
            update_kbd_leds(scp, scp->status);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case KDGETLED:             /* get keyboard LED status */
        if (scp == sc->cur_scp)
            save_kbd_state(scp, FALSE);
        *(int *)data = scp->status & LED_MASK;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
        case KBADDKBD:              /* add/remove keyboard to/from mux */
@@ -1496,7 +1506,7 @@ scioctl(struct dev_ioctl_args *ap)
                error = kbd_ioctl(sc->kbd, cmd, data);
                if (error == ENOIOCTL)
                        error = ENODEV;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return error;
 
     case CONS_SETKBD:          /* set the new keyboard */
@@ -1505,7 +1515,7 @@ scioctl(struct dev_ioctl_args *ap)
 
            newkbd = kbd_get_keyboard(*(int *)data);
            if (newkbd == NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return EINVAL;
            }
            error = 0;
@@ -1530,7 +1540,7 @@ scioctl(struct dev_ioctl_args *ap)
                    error = EPERM;      /* XXX */
                }
            }
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return error;
        }
 
@@ -1546,7 +1556,7 @@ scioctl(struct dev_ioctl_args *ap)
                syscons_unlock();
            }
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 
     case CONS_GETTERM:         /* get the current terminal emulator info */
@@ -1564,13 +1574,13 @@ scioctl(struct dev_ioctl_args *ap)
                strncpy(((term_info_t *)data)->ti_desc, sw->te_desc, 
                        sizeof(((term_info_t *)data)->ti_desc));
                ((term_info_t *)data)->ti_flags = 0;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return 0;
            } else {
                ((term_info_t *)data)->ti_name[0] = '\0';
                ((term_info_t *)data)->ti_desc[0] = '\0';
                ((term_info_t *)data)->ti_flags = 0;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return EINVAL;
            }
        }
@@ -1580,12 +1590,12 @@ scioctl(struct dev_ioctl_args *ap)
        error = sc_init_emulator(scp, ((term_info_t *)data)->ti_name);
        /* FIXME: what if scp == sc_console! XXX */
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 
     case GIO_SCRNMAP:          /* get output translation table */
        bcopy(&sc->scr_map, data, sizeof(sc->scr_map));
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case PIO_SCRNMAP:          /* set output translation table */
@@ -1593,7 +1603,7 @@ scioctl(struct dev_ioctl_args *ap)
        for (i=0; i<sizeof(sc->scr_map); i++) {
            sc->scr_rmap[sc->scr_map[i]] = i;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case GIO_KEYMAP:           /* get keyboard translation table */
@@ -1605,14 +1615,14 @@ scioctl(struct dev_ioctl_args *ap)
        error = kbd_ioctl(sc->kbd, cmd, data);
        if (error == ENOIOCTL)
            error = ENODEV;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 
 #ifndef SC_NO_FONT_LOADING
 
     case PIO_FONT8x8:          /* set 8x8 dot font */
        if (sc->fbi == NULL && !ISFONTAVAIL(sc->adp->va_flags)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENXIO;
        }
        syscons_lock();
@@ -1628,27 +1638,27 @@ scioctl(struct dev_ioctl_args *ap)
            sc_load_font(sc->cur_scp, 0, 8, sc->font_8, 0, 256);
        }
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case GIO_FONT8x8:          /* get 8x8 dot font */
        if (sc->fbi == NULL && !ISFONTAVAIL(sc->adp->va_flags)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENXIO;
        }
        if (sc->fonts_loaded & FONT_8) {
            bcopy(sc->font_8, data, 8*256);
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return 0;
        }
        else {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENXIO;
        }
 
     case PIO_FONT8x14:         /* set 8x14 dot font */
        if (sc->fbi == NULL && !ISFONTAVAIL(sc->adp->va_flags)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENXIO;
        }
        syscons_lock();
@@ -1666,27 +1676,27 @@ scioctl(struct dev_ioctl_args *ap)
            sc_load_font(sc->cur_scp, 0, 14, sc->font_14, 0, 256);
        }
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case GIO_FONT8x14:         /* get 8x14 dot font */
        if (sc->fbi == NULL && !ISFONTAVAIL(sc->adp->va_flags)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENXIO;
        }
        if (sc->fonts_loaded & FONT_14) {
            bcopy(sc->font_14, data, 14*256);
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return 0;
        }
        else {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENXIO;
         }
 
     case PIO_FONT8x16:         /* set 8x16 dot font */
        if (sc->fbi == NULL && !ISFONTAVAIL(sc->adp->va_flags)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENXIO;
        }
        syscons_lock();
@@ -1702,21 +1712,21 @@ scioctl(struct dev_ioctl_args *ap)
            sc_load_font(sc->cur_scp, 0, 16, sc->font_16, 0, 256);
        }
        syscons_unlock();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 
     case GIO_FONT8x16:         /* get 8x16 dot font */
        if (sc->fbi == NULL && !ISFONTAVAIL(sc->adp->va_flags)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENXIO;
        }
        if (sc->fonts_loaded & FONT_16) {
            bcopy(sc->font_16, data, 16*256);
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return 0;
        }
        else {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return ENXIO;
         }
 
@@ -1726,17 +1736,26 @@ scioctl(struct dev_ioctl_args *ap)
        break;
     }
 
+    lwkt_gettoken(&tp->t_token);
     error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, ap->a_cred);
     if (error != ENOIOCTL) {
-        lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+        lwkt_reltoken(&vga_token);
+
        return(error);
     }
+
     error = ttioctl(tp, cmd, data, flag);
     if (error != ENOIOCTL) {
-        lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+        lwkt_reltoken(&vga_token);
+
        return(error);
     }
-    lwkt_reltoken(&tty_token);
+
+    lwkt_reltoken(&tp->t_token);
+    lwkt_reltoken(&vga_token);
+
     return(ENOTTY);
 }
 
@@ -2411,10 +2430,10 @@ sc_fb_set_par(void *context, int pending)
 {
        sc_softc_t *sc = context;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        if (sc->fbi != NULL && sc->fbi->fbops.fb_set_par != NULL)
            sc->fbi->fbops.fb_set_par(sc->fbi);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
 }
 
 #if NSPLASH > 0
@@ -2423,7 +2442,7 @@ sc_fb_blank(void *context, int pending)
 {
        sc_softc_t *sc = context;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        if (sc->fbi != NULL && sc->fbi->fbops.fb_blank != NULL) {
                /* 0 == FB_BLANK_UNBLANK and 4 == FB_BLANK_POWERDOWN */
                if (sc->flags & SC_SCRN_BLANKED) {
@@ -2439,7 +2458,7 @@ sc_fb_blank(void *context, int pending)
                                cons_unavail = FALSE;
                }
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
 }
 
 static void
@@ -2939,7 +2958,7 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
 static void
 do_switch_scr(sc_softc_t *sc)
 {
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     vt_proc_alive(sc->new_scp);
 
     exchange_scr(sc);
@@ -2952,23 +2971,23 @@ do_switch_scr(sc_softc_t *sc)
        if (sc->unit == sc_console_unit && !sc->fb_blanked)
            cons_unavail = FALSE;
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 }
 
 static int
 vt_proc_alive(scr_stat *scp)
 {
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if (scp->proc) {
        if (scp->proc == pfindn(scp->pid)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return TRUE;
        }
        scp->proc = NULL;
        scp->smode.mode = VT_AUTO;
        DPRINTF(5, ("vt controlling process %d died\n", scp->pid));
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return FALSE;
 }
 
@@ -2977,9 +2996,9 @@ signal_vt_rel(scr_stat *scp)
 {
     struct proc *p;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if (scp->smode.mode != VT_PROCESS) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return FALSE;
     }
     scp->status |= SWITCH_WAIT_REL;
@@ -2988,7 +3007,7 @@ signal_vt_rel(scr_stat *scp)
     ksignal(p, scp->smode.relsig);
     PRELE(p);
     DPRINTF(5, ("sending relsig to %d\n", scp->pid));
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 
     return TRUE;
 }
@@ -2998,9 +3017,9 @@ signal_vt_acq(scr_stat *scp)
 {
     struct proc *p;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if (scp->smode.mode != VT_PROCESS) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return FALSE;
     }
     if (scp->sc->unit == sc_console_unit)
@@ -3011,7 +3030,7 @@ signal_vt_acq(scr_stat *scp)
     ksignal(p, scp->smode.acqsig);
     PRELE(p);
     DPRINTF(5, ("sending acqsig to %d\n", scp->pid));
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 
     return TRUE;
 }
@@ -3019,31 +3038,31 @@ signal_vt_acq(scr_stat *scp)
 static int
 finish_vt_rel(scr_stat *scp, int release)
 {
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if (scp == scp->sc->old_scp && scp->status & SWITCH_WAIT_REL) {
        scp->status &= ~SWITCH_WAIT_REL;
        if (release)
            do_switch_scr(scp->sc);
        else
            scp->sc->switch_in_progress = 0;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return EINVAL;
 }
 
 static int
 finish_vt_acq(scr_stat *scp)
 {
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if (scp == scp->sc->new_scp && scp->status & SWITCH_WAIT_ACQ) {
        scp->status &= ~SWITCH_WAIT_ACQ;
        scp->sc->switch_in_progress = 0;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return EINVAL;
 }
 
@@ -3052,7 +3071,7 @@ exchange_scr(sc_softc_t *sc)
 {
     scr_stat *scp;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     /* save the current state of video and keyboard */
     sc_move_cursor(sc->old_scp, sc->old_scp->xpos, sc->old_scp->ypos);
     if (!ISGRAPHSC(sc->old_scp))
@@ -3096,7 +3115,7 @@ exchange_scr(sc_softc_t *sc)
        taskqueue_enqueue(taskqueue_thread[0], sc->fb_set_par_task);
     }
 
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 }
 
 static void
@@ -3277,11 +3296,11 @@ scinit(int unit, int flags)
            col = 0;
            row = 0;
        } else {
-           lwkt_gettoken(&tty_token);
+           lwkt_gettoken(&vga_token);
            /* extract the hw cursor location and hide the cursor for now */
            (*vidsw[sc->adapter]->read_hw_cursor)(sc->adp, &col, &row);
            (*vidsw[sc->adapter]->set_hw_cursor)(sc->adp, -1, -1);
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
        }
 
        /* set up the first console */
@@ -3306,7 +3325,7 @@ scinit(int unit, int flags)
                                  GID_WHEEL, 0600, "ttyv%s",
                                  makedev_unit_b32(tbuf, unit * MAXCONS));
 
-           sc->dev[0]->si_tty = ttymalloc(sc->dev[0]->si_tty);
+           ttymalloc(&sc->dev[0]->si_tty);
            scp = alloc_scp(sc, sc->first_vty);
            sc->dev[0]->si_drv1 = scp;
        }
@@ -3423,7 +3442,7 @@ scterm(int unit, int flags)
     if (sc == NULL)
        return;                 /* shouldn't happen */
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
 #if NSPLASH > 0
     /* this console is no longer available for the splash screen */
     if (sc->flags & SC_SPLASH_SCRN) {
@@ -3462,6 +3481,7 @@ scterm(int unit, int flags)
        kfree(sc->dev, M_SYSCONS);
 #if 0
        /* XXX: We need a ttyunregister for this */
+       /* XXX: do not race tty token access */
        kfree(sc->tty, M_SYSCONS);
 #endif
 #ifndef SC_NO_FONT_LOADING
@@ -3474,7 +3494,7 @@ scterm(int unit, int flags)
     bzero(sc, sizeof(*sc));
     sc->keyboard = -1;
     sc->adapter = -1;
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 }
 #endif
 
@@ -3483,7 +3503,7 @@ scshutdown(void *arg, int howto)
 {
     /* assert(sc_console != NULL) */
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     syscons_lock();
     sc_touch_scrn_saver();
     if (!cold && sc_console
@@ -3493,7 +3513,7 @@ scshutdown(void *arg, int howto)
     }
     shutdown_in_progress = TRUE;
     syscons_unlock();
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 }
 
 int
@@ -3503,12 +3523,12 @@ sc_clean_up(scr_stat *scp, int need_unlock)
     int error;
 #endif /* NSPLASH */
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if (scp->sc->flags & SC_SCRN_BLANKED) {
        sc_touch_scrn_saver();
 #if NSPLASH > 0
        if ((error = wait_scrn_saver_stop(scp->sc, need_unlock))) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return error;
        }
 #endif /* NSPLASH */
@@ -3516,7 +3536,7 @@ sc_clean_up(scr_stat *scp, int need_unlock)
     scp->status |= MOUSE_HIDDEN;
     sc_remove_mouse_image(scp);
     sc_remove_cutmarking(scp);
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return 0;
 }
 
@@ -3526,7 +3546,7 @@ sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard)
     sc_vtb_t new;
     sc_vtb_t old;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     old = scp->vtb;
     sc_vtb_init(&new, VTB_MEMORY, scp->xsize, scp->ysize, NULL, wait);
     if (!discard && (old.vtb_flags & VTB_VALID)) {
@@ -3547,7 +3567,7 @@ sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard)
     /* move the mouse cursor at the center of the screen */
     sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2);
 #endif
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 }
 
 static scr_stat *
@@ -3575,7 +3595,7 @@ alloc_scp(sc_softc_t *sc, int vty)
 }
 
 /*
- * NOTE: Must be called with tty_token held.
+ * NOTE: Must be called with vga_token held.
  */
 static void
 init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
@@ -3591,9 +3611,9 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
     scp->fbi_generation = sc->fbi_generation;
     callout_init_lk(&scp->blink_screen_ch, &syscons_blink_lk);
     if (scp->sc->fbi == NULL) {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        (*vidsw[sc->adapter]->get_info)(sc->adp, scp->mode, &info);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
     }
     if (scp->sc->fbi != NULL) {
        scp->xpixel = sc->fbi->width;
@@ -3760,9 +3780,9 @@ scgetc(sc_softc_t *sc, u_int flags)
     int f;
     int i;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if (sc->kbd == NULL) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return NOKEY;
     }
 
@@ -3783,7 +3803,7 @@ next_code:
            if (!(flags & SCGETC_CN))
                sc_bell(scp, bios_value.bell_pitch, BELL_DURATION);
        } else if (c == NOKEY) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return c;
        } else {
            break;
@@ -3799,7 +3819,7 @@ next_code:
        add_keyboard_randomness(c);
 
     if (scp->kbd_mode != K_XLATE) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return KEYCHAR(c);
     }
 
@@ -3911,7 +3931,7 @@ next_code:
 
            case BTAB:
                if (!(sc->flags & SC_SCRN_BLANKED)) {
-                    lwkt_reltoken(&tty_token);
+                    lwkt_reltoken(&vga_token);
                    return c;
                }
                break;
@@ -3966,9 +3986,9 @@ next_code:
            case DBG:
 #ifndef SC_DISABLE_DDBKEY
 #ifdef DDB
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                Debugger("manual escape to debugger");
-               lwkt_gettoken(&tty_token);
+               lwkt_gettoken(&vga_token);
 #else
                kprintf("No debugger in kernel\n");
 #endif
@@ -4021,7 +4041,7 @@ next_code:
                }
                /* assert(c & FKEY) */
                if (!(sc->flags & SC_SCRN_BLANKED)) {
-                   lwkt_reltoken(&tty_token);
+                   lwkt_reltoken(&vga_token);
                    return c;
                }
                break;
@@ -4030,7 +4050,7 @@ next_code:
        } else {
            /* regular keys (maybe MKEY is set) */
            if (!(sc->flags & SC_SCRN_BLANKED)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return c;
            }
        }
@@ -4044,17 +4064,17 @@ scmmap(struct dev_mmap_args *ap)
 {
     scr_stat *scp;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     scp = SC_STAT(ap->a_head.a_dev);
     if (scp != scp->sc->cur_scp) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return EINVAL;
     }
     if (scp->sc->fbi != NULL) {
        size_t sz =
            roundup(scp->sc->fbi->height * scp->sc->fbi->stride, PAGE_SIZE);
        if (ap->a_offset > sz - PAGE_SIZE) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&vga_token);
            return EINVAL;
        } else {
            ap->a_result = atop(scp->sc->fbi->paddr + ap->a_offset);
@@ -4064,7 +4084,7 @@ scmmap(struct dev_mmap_args *ap)
                                                        ap->a_offset,
                                                        ap->a_nprot);
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return(0);
 }
 
@@ -4133,16 +4153,16 @@ set_mode(scr_stat *scp)
 {
     video_info_t info;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     /* reject unsupported mode */
     if (scp->sc->fbi == NULL && (*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, scp->mode, &info)) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return 1;
     }
 
     /* if this vty is not currently showing, do nothing */
     if (scp != scp->sc->cur_scp) {
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return 0;
     }
 
@@ -4186,7 +4206,7 @@ set_mode(scr_stat *scp)
     sc_set_cursor_image(scp);
 
 done:
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return 0;
 }
 
@@ -4270,18 +4290,21 @@ sc_paste(scr_stat *scp, u_char *p, int count)
     if (scp->kbd_mode != K_XLATE)
        return;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if (scp->status & MOUSE_VISIBLE) {
        tp = VIRTUAL_TTY(scp->sc, scp->sc->cur_scp->index);
+       lwkt_gettoken(&tp->t_token);
        if (!ISTTYOPEN(tp)) {
-           lwkt_reltoken(&tty_token);
+           lwkt_reltoken(&tp->t_token);
+           lwkt_reltoken(&vga_token);
            return;
        }
        rmap = scp->sc->scr_rmap;
        for (; count > 0; --count)
            (*linesw[tp->t_line].l_rint)(rmap[*p++], tp);
+       lwkt_reltoken(&tp->t_token);
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 }
 
 void
index e810b81..30f225b 100644 (file)
@@ -1271,7 +1271,8 @@ sioopen(struct dev_open_args *ap)
        if (mynor & CONTROL_MASK)
                return (0);
        lwkt_gettoken(&tty_token);
-       tp = dev->si_tty = com->tp = ttymalloc(com->tp);
+       tp = ttymalloc(&com->tp);
+       dev->si_tty = tp;
        crit_enter();
        /*
         * We jump to this label after all non-interrupted sleeps to pick
index 3b3cd87..7b8ac83 100644 (file)
@@ -76,10 +76,10 @@ bmp_start(video_adapter_t *adp)
     video_info_t       info;
     int                        i;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if ((bmp_decoder.data == NULL) || (bmp_decoder.data_size <= 0)) {
        kprintf("splash_bmp: No bitmap file found\n");
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return ENODEV;
     }
     for (i = 0; modes[i] >= 0; ++i) {
@@ -93,7 +93,7 @@ bmp_start(video_adapter_t *adp)
        kprintf("splash_bmp: No appropriate video mode found\n");
     if (bootverbose)
        kprintf("bmp_start(): splash_mode:%d\n", splash_mode);
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return ((splash_mode < 0) ? ENODEV : 0);
 }
 
@@ -114,16 +114,16 @@ bmp_splash(video_adapter_t *adp, int on)
     struct timeval     tv;
     int                        i;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     if (on) {
        if (!splash_on) {
            /* set up the video mode and draw something */
            if ((*vidsw[adp->va_index]->set_mode)(adp, splash_mode)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return 1;
            }
            if (bmp_Draw(adp)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return 1;
            }
            (*vidsw[adp->va_index]->save_palette)(adp, pal);
@@ -159,12 +159,12 @@ bmp_splash(video_adapter_t *adp, int on)
                time_stamp = tv.tv_sec;
            }
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
     } else {
        /* the video mode will be restored by the caller */
        splash_on = FALSE;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
     }
 }
@@ -258,7 +258,7 @@ bmp_SetPix(BMP_INFO *info, int x, int y, u_char val)
     if ((x < 0) || (x >= info->swidth) || (y < 0) || (y >= info->sheight))
        return;
     
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     /* 
      * calculate offset into video memory;
      * because 0,0 is bottom-left for DIB, we have to convert.
@@ -295,7 +295,7 @@ bmp_SetPix(BMP_INFO *info, int x, int y, u_char val)
        *(info->vidmem+sofs) = val;
        break;
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 }
     
 /*
@@ -573,7 +573,7 @@ bmp_Draw(video_adapter_t *adp)
        return(1);
     }
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     /* clear the screen */
     bmp_info.vidmem = (u_char *)adp->va_window;
     bmp_info.adp = adp;
@@ -610,6 +610,6 @@ bmp_Draw(video_adapter_t *adp)
     for (line = 0; (line < bmp_info.height) && bmp_info.index; line++) {
        bmp_DecodeLine(&bmp_info, line);
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return(0);
 }
index 4eb1b21..73b67af 100644 (file)
@@ -165,37 +165,37 @@ vid_register(video_adapter_t *adp)
 
        adp->va_index = index;
        adp->va_token = NULL;
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        SET_FOREACH(list, videodriver_set) {
                p = *list;
                if (strcmp(p->name, adp->va_name) == 0) {
                        adapter[index] = adp;
                        vidsw[index] = p->vidsw;
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&vga_token);
                        return index;
                }
        }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return -1;
 }
 
 int
 vid_unregister(video_adapter_t *adp)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        if ((adp->va_index < 0) || (adp->va_index >= adapters)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return ENOENT;
        }
        if (adapter[adp->va_index] != adp) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&vga_token);
                return ENOENT;
        }
 
        adapter[adp->va_index] = NULL;
        vidsw[adp->va_index] = NULL;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return 0;
 }
 
@@ -206,16 +206,16 @@ vid_get_switch(char *name)
        const video_driver_t **list;
        const video_driver_t *p;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        SET_FOREACH(list, videodriver_set) {
                p = *list;
                if (strcmp(p->name, name) == 0) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&vga_token);
                        return p->vidsw;
                }
        }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return NULL;
 }
 
@@ -495,7 +495,7 @@ int genfbread(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio,
        int error;
        int len;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        error = 0;
        size = adp->va_buffer_size/adp->va_info.vi_planes;
        while (uio->uio_resid > 0) {
@@ -512,7 +512,7 @@ int genfbread(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio,
                if (error)
                        break;
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 }
 
@@ -529,11 +529,11 @@ int genfbioctl(genfb_softc_t *sc, video_adapter_t *adp, u_long cmd,
 
        if (adp == NULL)        /* XXX */
                return ENXIO;
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        error = (*vidsw[adp->va_index]->ioctl)(adp, cmd, arg);
        if (error == ENOIOCTL)
                error = ENODEV;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 }
 
@@ -542,9 +542,9 @@ int genfbmmap(genfb_softc_t *sc, video_adapter_t *adp, vm_offset_t offset,
 {
        int error;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        error = (*vidsw[adp->va_index]->mmap)(adp, offset, prot);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return (error);
 }
 
@@ -656,7 +656,7 @@ fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
        error = 0;
        crit_enter();
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
        switch (cmd) {
 
        case FBIO_ADAPTER:      /* get video adapter index */
@@ -766,6 +766,6 @@ fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
        }
 
        crit_exit();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&vga_token);
        return error;
 }
index 5bb59fa..22586c5 100644 (file)
@@ -102,16 +102,16 @@ typedef struct video_switch {
 
 #define save_palette(adp, pal)                         \
        do {                                            \
-               lwkt_gettoken(&tty_token);              \
+               lwkt_gettoken(&vga_token);              \
                (*vidsw[(adp)->va_index]->save_palette)((adp), (pal)); \
-               lwkt_reltoken(&tty_token);              \
+               lwkt_reltoken(&vga_token);              \
        } while (0)
 
 #define load_palette(adp, pal)                         \
        do {                                            \
-               lwkt_gettoken(&tty_token);              \
+               lwkt_gettoken(&vga_token);              \
                (*vidsw[(adp)->va_index]->load_palette)((adp), (pal)); \
-               lwkt_reltoken(&tty_token);              \
+               lwkt_reltoken(&vga_token);              \
        } while (0)
 
 #define get_mode_info(adp, mode, buf)                  \
@@ -123,17 +123,17 @@ typedef struct video_switch {
 #if 0 /* XXX conflicts with syscons' set_border() */
 #define set_border(adp, border)                                \
        do {                                            \
-               lwkt_gettoken(&tty_token);              \
+               lwkt_gettoken(&vga_token);              \
                (*vidsw[(adp)->va_index]->set_border)((adp), (border)); \
-               lwkt_reltoken(&tty_token);              \
+               lwkt_reltoken(&vga_token);              \
        } while (0)
 #endif
 
 #define set_origin(adp, o)                             \
        do {                                            \
-               lwkt_gettoken(&tty_token);              \
+               lwkt_gettoken(&vga_token);              \
                (*vidsw[(adp)->va_index]->set_win_org)(adp, o); \
-               lwkt_reltoken(&tty_token);              \
+               lwkt_reltoken(&vga_token);              \
        } while (0)
 
 /* XXX - add more macros */
index 4721d52..b5d8b31 100644 (file)
@@ -1005,7 +1005,7 @@ vga_set_mode(video_adapter_t *adp, int mode)
     if (vga_get_info(adp, mode, &info))
        return EINVAL;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
 
 #if VGA_DEBUG > 1
     kprintf("vga_set_mode(): setting mode %d\n", mode);
@@ -1112,7 +1112,7 @@ setup_grmode:
        break;
 
     default:
-        lwkt_reltoken(&tty_token);
+        lwkt_reltoken(&vga_token);
        return EINVAL;
     }
 
@@ -1123,7 +1123,7 @@ setup_grmode:
     /* move hardware cursor out of the way */
     (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
 
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
     return 0;
 #else /* VGA_NO_MODE_CHANGE */
     return ENODEV;
@@ -1737,7 +1737,7 @@ planar_fill(video_adapter_t *adp, int val)
     int at;                    /* position in the frame buffer */
     int l;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     outw(GDCIDX, 0x0005);              /* read mode 0, write mode 0 */
     outw(GDCIDX, 0x0003);              /* data rotate/function select */
     outw(GDCIDX, 0x0f01);              /* set/reset enable */
@@ -1754,7 +1754,7 @@ planar_fill(video_adapter_t *adp, int val)
     }
     outw(GDCIDX, 0x0000);              /* set/reset */
     outw(GDCIDX, 0x0001);              /* set/reset enable */
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 }
 
 static void
@@ -1764,7 +1764,7 @@ packed_fill(video_adapter_t *adp, int val)
     int at;                    /* position in the frame buffer */
     int l;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     at = 0;
     length = adp->va_line_width*adp->va_info.vi_height;
     while (length > 0) {
@@ -1774,7 +1774,7 @@ packed_fill(video_adapter_t *adp, int val)
        length -= l;
        at += l;
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 }
 
 static void
@@ -1784,7 +1784,7 @@ direct_fill(video_adapter_t *adp, int val)
     int at;                    /* position in the frame buffer */
     int l;
 
-    lwkt_gettoken(&tty_token);
+    lwkt_gettoken(&vga_token);
     at = 0;
     length = adp->va_line_width*adp->va_info.vi_height;
     while (length > 0) {
@@ -1804,7 +1804,7 @@ direct_fill(video_adapter_t *adp, int val)
        length -= l;
        at += l;
     }
-    lwkt_reltoken(&tty_token);
+    lwkt_reltoken(&vga_token);
 }
 
 static int
index 0d53256..f97b822 100644 (file)
@@ -725,6 +725,7 @@ enterpgrp(struct proc *p, pid_t pgid, int mksess)
                        sess = kmalloc(sizeof(struct session), M_SESSION,
                                       M_WAITOK | M_ZERO);
                        lwkt_gettoken(&p->p_token);
+                       sess->s_prg = prg;
                        sess->s_leader = p;
                        sess->s_sid = p->p_pid;
                        sess->s_count = 1;
@@ -855,12 +856,10 @@ sess_rele(struct session *sess)
                cpu_ccfence();
                KKASSERT(count > 0);
                if (count == 1) {
-                       lwkt_gettoken(&tty_token);
                        lwkt_gettoken(&prg->proc_token);
                        if (atomic_cmpset_int(&sess->s_count, 1, 0))
                                break;
                        lwkt_reltoken(&prg->proc_token);
-                       lwkt_reltoken(&tty_token);
                        /* retry */
                } else {
                        if (atomic_cmpset_int(&sess->s_count, count, count - 1))
@@ -870,7 +869,7 @@ sess_rele(struct session *sess)
        }
 
        /*
-        * Successful 1->0 transition and tty_token is held.
+        * Successful 1->0 transition and prg->proc_token is held.
         */
        LIST_REMOVE(sess, s_list);
        if (pid_doms[sess->s_sid % PIDSEL_DOMAINS] != (uint8_t)time_second)
@@ -892,7 +891,6 @@ sess_rele(struct session *sess)
                ttyunhold(tp);
        }
        lwkt_reltoken(&prg->proc_token);
-       lwkt_reltoken(&tty_token);
 
        kfree(sess, M_SESSION);
 }
index 8c96d2b..8d92b78 100644 (file)
@@ -140,6 +140,8 @@ struct lwkt_token kvm_token = LWKT_TOKEN_INITIALIZER(kvm_token);
 struct lwkt_token sigio_token = LWKT_TOKEN_INITIALIZER(sigio_token);
 struct lwkt_token tty_token = LWKT_TOKEN_INITIALIZER(tty_token);
 struct lwkt_token vnode_token = LWKT_TOKEN_INITIALIZER(vnode_token);
+struct lwkt_token vga_token = LWKT_TOKEN_INITIALIZER(vga_token);
+struct lwkt_token kbd_token = LWKT_TOKEN_INITIALIZER(kbd_token);
 
 /*
  * Exponential backoff (exclusive tokens) and TSC windowing (shared tokens)
index de3f4d8..aa11d67 100644 (file)
@@ -219,8 +219,7 @@ static TAILQ_HEAD(, tty) tty_list = TAILQ_HEAD_INITIALIZER(tty_list);
 int
 ttyopen(cdev_t device, struct tty *tp)
 {
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        tp->t_dev = device;
        if (!ISSET(tp->t_state, TS_ISOPEN)) {
                SET(tp->t_state, TS_ISOPEN);
@@ -230,8 +229,8 @@ ttyopen(cdev_t device, struct tty *tp)
                bzero(&tp->t_winsize, sizeof(tp->t_winsize));
        }
        ttsetwater(tp);
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&tp->t_token);
+
        return (0);
 }
 
@@ -247,8 +246,7 @@ ttyopen(cdev_t device, struct tty *tp)
 int
 ttyclose(struct tty *tp)
 {
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        funsetown(&tp->t_sigio);
        if (constty == tp)
                constty = NULL;
@@ -262,8 +260,8 @@ ttyclose(struct tty *tp)
        tp->t_line = TTYDISC;
        ttyclearsession(tp);
        tp->t_state &= TS_REGISTERED;   /* clear all bits except */
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&tp->t_token);
+
        return (0);
 }
 
@@ -281,9 +279,10 @@ void
 ttyclearsession(struct tty *tp)
 {
        struct session *sp;
+       struct procglob *prg;
        struct pgrp *opgrp;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        opgrp = tp->t_pgrp;
        tp->t_pgrp = NULL;
        if (opgrp) {
@@ -291,8 +290,16 @@ ttyclearsession(struct tty *tp)
                opgrp = NULL;
        }
 
+again:
        if ((sp = tp->t_session) != NULL) {
+               prg = sp->s_prg;
+               lwkt_gettoken(&prg->proc_token);
+               if (sp != tp->t_session) {
+                       lwkt_reltoken(&prg->proc_token);
+                       goto again;
+               }
                tp->t_session = NULL;
+
 #ifdef TTY_DO_FULL_CLOSE
                /* FULL CLOSE (not yet) */
                if (sp->s_ttyp == tp) {
@@ -303,8 +310,9 @@ ttyclearsession(struct tty *tp)
                                "%p/%p\n", sp->s_ttyp, tp);
                }
 #endif
+               lwkt_reltoken(&prg->proc_token);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*
@@ -320,15 +328,17 @@ void
 ttyclosesession(struct session *sp, int dorevoke)
 {
        struct vnode *vp;
+       struct procglob *prg;
 
-       lwkt_gettoken(&tty_token);
+       prg = sp->s_prg;
+       lwkt_gettoken(&prg->proc_token);
 retry:
        /*
         * There may not be a controlling terminal or it may have been closed
         * out from under us.
         */
        if ((vp = sp->s_ttyvp) == NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&prg->proc_token);
                return;
        }
 
@@ -367,7 +377,7 @@ retry:
                sp->s_ttyvp = NULL;
        }
        vrele(vp);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&prg->proc_token);
 }
 
 #define        FLUSHQ(q) {                                                     \
@@ -391,7 +401,7 @@ ttyinput(int c, struct tty *tp)
        cc_t *cc;
        int i, err;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        /*
         * If input is pending take it first.
         */
@@ -427,7 +437,7 @@ ttyinput(int c, struct tty *tp)
                CLR(c, TTY_ERRORMASK);
                if (ISSET(err, TTY_BI)) {
                        if (ISSET(iflag, IGNBRK)) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (0);
                        }
                        if (ISSET(iflag, BRKINT)) {
@@ -440,7 +450,7 @@ ttyinput(int c, struct tty *tp)
                } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
                        || ISSET(err, TTY_FE)) {
                        if (ISSET(iflag, IGNPAR)) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (0);
                        }
                        else if (ISSET(iflag, PARMRK)) {
@@ -532,11 +542,11 @@ parmrk:
                                if (!ISSET(tp->t_state, TS_TTSTOP)) {
                                        SET(tp->t_state, TS_TTSTOP);
                                        (*tp->t_stop)(tp, 0);
-                                       lwkt_reltoken(&tty_token);
+                                       lwkt_reltoken(&tp->t_token);
                                        return (0);
                                }
                                if (!CCEQ(cc[VSTART], c)) {
-                                       lwkt_reltoken(&tty_token);
+                                       lwkt_reltoken(&tp->t_token);
                                        return (0);
                                }
                                /*
@@ -552,7 +562,7 @@ parmrk:
                 */
                if (c == '\r') {
                        if (ISSET(iflag, IGNCR)) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (0);
                        }
                        else if (ISSET(iflag, ICRNL))
@@ -713,14 +723,14 @@ endcase:
         */
        if (ISSET(tp->t_state, TS_TTSTOP) &&
            !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (0);
        }
 restartoutput:
        CLR(tp->t_lflag, FLUSHO);
        CLR(tp->t_state, TS_TTSTOP);
 startoutput:
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (ttstart(tp));
 }
 
@@ -736,20 +746,20 @@ ttyoutput(int c, struct tty *tp)
        tcflag_t oflag;
        int col;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        oflag = tp->t_oflag;
        if (!ISSET(oflag, OPOST)) {
                if (ISSET(tp->t_lflag, FLUSHO)) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (-1);
                }
                if (clist_putc(c, &tp->t_outq)) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (c);
                }
                tk_nout++;
                tp->t_outcc++;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (-1);
        }
        /*
@@ -763,18 +773,16 @@ ttyoutput(int c, struct tty *tp)
            ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
                c = 8 - (tp->t_column & 7);
                if (!ISSET(tp->t_lflag, FLUSHO)) {
-                       crit_enter();           /* Don't interrupt tabs. */
                        c -= b_to_q("        ", c, &tp->t_outq);
                        tk_nout += c;
                        tp->t_outcc += c;
-                       crit_exit();
                }
                tp->t_column += c;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (c ? -1 : '\t');
        }
        if (c == CEOT && ISSET(oflag, ONOEOT)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (-1);
        }
 
@@ -786,7 +794,7 @@ ttyoutput(int c, struct tty *tp)
                tk_nout++;
                tp->t_outcc++;
                if (!ISSET(tp->t_lflag, FLUSHO) && clist_putc('\r', &tp->t_outq)) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (c);
                }
        }
@@ -795,14 +803,14 @@ ttyoutput(int c, struct tty *tp)
                c = '\n';
        /* If ONOCR is set, don't transmit CRs when on column 0. */
        else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (-1);
        }
 
        tk_nout++;
        tp->t_outcc++;
        if (!ISSET(tp->t_lflag, FLUSHO) && clist_putc(c, &tp->t_outq)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (c);
        }
 
@@ -829,7 +837,8 @@ ttyoutput(int c, struct tty *tp)
                break;
        }
        tp->t_column = col;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+
        return (-1);
 }
 
@@ -850,7 +859,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
        int error;
 
        KKASSERT(p);
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        lwkt_gettoken(&p->p_token);
 
        /* If the ioctl involves modification, hang if in the background. */
@@ -882,7 +891,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                    !SIGISMEMBER(lp->lwp_sigmask, SIGTTOU)) {
                        if (p->p_pgrp->pg_jobc == 0) {
                                lwkt_reltoken(&p->p_token);
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (EIO);
                        }
                        pgsignal(p->p_pgrp, SIGTTOU, 1);
@@ -890,7 +899,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                                         0);
                        if (error) {
                                lwkt_reltoken(&p->p_token);
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (error);
                        }
                }
@@ -899,17 +908,13 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
 
        switch (cmd) {                  /* Process the ioctl. */
        case FIOASYNC:                  /* set/clear async i/o */
-               crit_enter();
                if (*(int *)data)
                        SET(tp->t_state, TS_ASYNC);
                else
                        CLR(tp->t_state, TS_ASYNC);
-               crit_exit();
                break;
        case FIONREAD:                  /* get # bytes to read */
-               crit_enter();
                *(int *)data = ttnread(tp);
-               crit_exit();
                break;
 
        case FIOSETOWN:
@@ -919,30 +924,28 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                 */
                if (tp->t_session != NULL && !isctty(p, tp)) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (ENOTTY);
                }
 
                error = fsetown(*(int *)data, &tp->t_sigio);
                if (error) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (error);
                }
                break;
        case FIOGETOWN:
                if (tp->t_session != NULL && !isctty(p, tp)) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (ENOTTY);
                }
                *(int *)data = fgetown(&tp->t_sigio);
                break;
 
        case TIOCEXCL:                  /* set exclusive use of tty */
-               crit_enter();
                SET(tp->t_state, TS_XCLUDE);
-               crit_exit();
                break;
        case TIOCFLUSH: {               /* flush buffers */
                int flags = *(int *)data;
@@ -959,13 +962,13 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                        if (constty && constty != tp &&
                            ISSET(constty->t_state, TS_CONNECTED)) {
                                lwkt_reltoken(&p->p_token);
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (EBUSY);
                        }
 #ifndef        UCONSOLE
                        if ((error = priv_check(td, PRIV_ROOT)) != 0) {
                                lwkt_reltoken(&p->p_token);
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (error);
                        }
 #endif
@@ -977,7 +980,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                error = ttywait(tp);
                if (error) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (error);
                }
                break;
@@ -996,7 +999,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
        case TIOCGPGRP:                 /* get pgrp of tty */
                if (!isctty(p, tp)) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (ENOTTY);
                }
                *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
@@ -1004,22 +1007,18 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
        case TIOCGSID:                  /* get sid of tty */
                if (!isctty(p, tp)) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (ENOTTY);
                }
                *(int *)data = tp->t_session->s_sid;
                break;
 #ifdef TIOCHPCL
        case TIOCHPCL:                  /* hang up on last close */
-               crit_enter();
                SET(tp->t_cflag, HUPCL);
-               crit_exit();
                break;
 #endif
        case TIOCNXCL:                  /* reset exclusive use of tty */
-               crit_enter();
                CLR(tp->t_state, TS_XCLUDE);
-               crit_exit();
                break;
        case TIOCOUTQ:                  /* output queue size */
                *(int *)data = tp->t_outq.c_cc;
@@ -1035,16 +1034,14 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                        t->c_ispeed = tp->t_ospeed;
                if (t->c_ispeed == 0) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (EINVAL);
                }
-               crit_enter();
                if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
                        error = ttywait(tp);
                        if (error) {
-                               crit_exit();
                                lwkt_reltoken(&p->p_token);
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (error);
                        }
                        if (cmd == TIOCSETAF)
@@ -1055,9 +1052,8 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                         * Set device hardware.
                         */
                        if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
-                               crit_exit();
                                lwkt_reltoken(&p->p_token);
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (error);
                        }
                        if (ISSET(t->c_cflag, CLOCAL) &&
@@ -1125,7 +1121,6 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                    t->c_cc[VTIME] != tp->t_cc[VTIME])
                        ttwakeup(tp);
                bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
-               crit_exit();
                break;
        }
        case TIOCSETD: {                /* set line discipline */
@@ -1134,57 +1129,48 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
 
                if ((u_int)t >= nlinesw) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (ENXIO);
                }
                if (t != tp->t_line) {
-                       crit_enter();
                        (*linesw[tp->t_line].l_close)(tp, flag);
                        error = (*linesw[t].l_open)(device, tp);
                        if (error) {
                                (void)(*linesw[tp->t_line].l_open)(device, tp);
-                               crit_exit();
                                lwkt_reltoken(&p->p_token);
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (error);
                        }
                        tp->t_line = t;
-                       crit_exit();
                }
                break;
        }
        case TIOCSTART:                 /* start output, like ^Q */
-               crit_enter();
                if (ISSET(tp->t_state, TS_TTSTOP) ||
                    ISSET(tp->t_lflag, FLUSHO)) {
                        CLR(tp->t_lflag, FLUSHO);
                        CLR(tp->t_state, TS_TTSTOP);
                        ttstart(tp);
                }
-               crit_exit();
                break;
        case TIOCSTI:                   /* simulate terminal input */
                if ((flag & FREAD) == 0 && priv_check(td, PRIV_ROOT)) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (EPERM);
                }
                if (!isctty(p, tp) && priv_check(td, PRIV_ROOT)) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (EACCES);
                }
-               crit_enter();
                (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
-               crit_exit();
                break;
        case TIOCSTOP:                  /* stop output, like ^S */
-               crit_enter();
                if (!ISSET(tp->t_state, TS_TTSTOP)) {
                        SET(tp->t_state, TS_TTSTOP);
                        (*tp->t_stop)(tp, 0);
                }
-               crit_exit();
                break;
        case TIOCSCTTY:                 /* become controlling tty */
                /* Session ctty vnode pointer set in vnode layer. */
@@ -1192,7 +1178,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                    ((p->p_session->s_ttyvp || tp->t_session) &&
                    (tp->t_session != p->p_session))) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (EPERM);
                }
                ttyhold(tp);
@@ -1215,12 +1201,12 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
 
                if (!isctty(p, tp)) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (ENOTTY);
                }
                else if (pgid < 1 || pgid > PID_MAX) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (EINVAL);
                } else {
                        struct pgrp *pgrp = pgfind(pgid);
@@ -1228,7 +1214,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                                if (pgrp)
                                        pgrel(pgrp);
                                lwkt_reltoken(&p->p_token);
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (EPERM);
                        }
                        opgrp = tp->t_pgrp;
@@ -1241,9 +1227,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                break;
        }
        case TIOCSTAT:                  /* simulate control-T */
-               crit_enter();
                ttyinfo(tp);
-               crit_exit();
                break;
        case TIOCSWINSZ:                /* set window size */
                if (bcmp((caddr_t)&tp->t_winsize, data,
@@ -1256,7 +1240,7 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                error = priv_check(td, PRIV_ROOT);
                if (error) {
                        lwkt_reltoken(&p->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (error);
                }
                tp->t_timeout = *(int *)data * hz;
@@ -1268,11 +1252,11 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
                break;
        default:
                lwkt_reltoken(&p->p_token);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (ENOIOCTL);
        }
        lwkt_reltoken(&p->p_token);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (0);
 }
 
@@ -1291,7 +1275,7 @@ ttykqfilter(struct dev_kqfilter_args *ap)
 
        ap->a_result = 0;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        switch (kn->kn_filter) {
        case EVFILT_READ:
                klist = &tp->t_rkq.ki_note;
@@ -1303,10 +1287,10 @@ ttykqfilter(struct dev_kqfilter_args *ap)
                break;
        default:
                ap->a_result = EOPNOTSUPP;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (0);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        kn->kn_hook = (caddr_t)dev;
        knote_insert(klist, kn);
 
@@ -1318,9 +1302,9 @@ filt_ttyrdetach(struct knote *kn)
 {
        struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        knote_remove(&tp->t_rkq.ki_note, kn);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 static int
@@ -1328,14 +1312,14 @@ filt_ttyread(struct knote *kn, long hint)
 {
        struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        kn->kn_data = ttnread(tp);
        if (ISSET(tp->t_state, TS_ZOMBIE)) {
                kn->kn_flags |= (EV_EOF | EV_NODATA);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (1);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (kn->kn_data > 0);
 }
 
@@ -1344,9 +1328,9 @@ filt_ttywdetach(struct knote *kn)
 {
        struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        knote_remove(&tp->t_wkq.ki_note, kn);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 static int
@@ -1355,28 +1339,27 @@ filt_ttywrite(struct knote *kn, long hint)
        struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
        int ret;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        kn->kn_data = tp->t_outq.c_cc;
        if (ISSET(tp->t_state, TS_ZOMBIE)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (1);
        }
        ret = (kn->kn_data <= tp->t_olowat &&
            ISSET(tp->t_state, TS_CONNECTED));
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return ret;
 }
 
 /*
- * Must be called while in a critical section.
- * NOTE: tty_token must be held.
+ * NOTE: tp->t_token must be held.
  */
 static int
 ttnread(struct tty *tp)
 {
        int nread;
 
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
+       ASSERT_LWKT_TOKEN_HELD(&tp->t_token);
        if (ISSET(tp->t_lflag, PENDIN))
                ttypend(tp);
        nread = tp->t_canq.c_cc;
@@ -1397,8 +1380,7 @@ ttywait(struct tty *tp)
        int error;
 
        error = 0;
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
               ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
                (*tp->t_oproc)(tp);
@@ -1418,8 +1400,8 @@ ttywait(struct tty *tp)
        }
        if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
                error = EIO;
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&tp->t_token);
+
        return (error);
 }
 
@@ -1442,8 +1424,7 @@ ttywflush(struct tty *tp)
 void
 ttyflush(struct tty *tp, int rw)
 {
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
 #if 0
 again:
 #endif
@@ -1501,8 +1482,7 @@ again:
                FLUSHQ(&tp->t_outq);
                ttwwakeup(tp);
        }
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*
@@ -1511,9 +1491,7 @@ again:
 void
 termioschars(struct termios *t)
 {
-       lwkt_gettoken(&tty_token);
        bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
-       lwkt_reltoken(&tty_token);
 }
 
 /*
@@ -1522,9 +1500,9 @@ termioschars(struct termios *t)
 void
 ttychars(struct tty *tp)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        termioschars(&tp->t_termios);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*
@@ -1535,13 +1513,13 @@ ttychars(struct tty *tp)
 void
 ttyblock(struct tty *tp)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        SET(tp->t_state, TS_TBLOCK);
        if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
            clist_putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
                CLR(tp->t_state, TS_TBLOCK);    /* try again later */
        ttstart(tp);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*
@@ -1552,22 +1530,22 @@ ttyblock(struct tty *tp)
 static void
 ttyunblock(struct tty *tp)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        CLR(tp->t_state, TS_TBLOCK);
        if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
            clist_putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
                SET(tp->t_state, TS_TBLOCK);    /* try again later */
        ttstart(tp);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 int
 ttstart(struct tty *tp)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        if (tp->t_oproc != NULL)        /* XXX: Kludge for pty. */
                (*tp->t_oproc)(tp);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (0);
 }
 
@@ -1577,26 +1555,30 @@ ttstart(struct tty *tp)
 int
 ttylclose(struct tty *tp, int flag)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        if (flag & FNONBLOCK || ttywflush(tp))
                ttyflush(tp, FREAD | FWRITE);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (0);
 }
 
 void
 ttyhold(struct tty *tp)
 {
+       lwkt_gettoken(&tp->t_token);
        ++tp->t_refs;
+       lwkt_reltoken(&tp->t_token);
 }
 
 void
 ttyunhold(struct tty *tp)
 {
+       lwkt_gettoken(&tp->t_token);
        if (tp->t_unhold)
                tp->t_unhold(tp);
        else
                --tp->t_refs;
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*
@@ -1607,7 +1589,7 @@ ttyunhold(struct tty *tp)
 int
 ttymodem(struct tty *tp, int flag)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
                /*
                 * MDMBUF: do flow control according to carrier flag
@@ -1635,7 +1617,7 @@ ttymodem(struct tty *tp, int flag)
                        if (tp->t_session && tp->t_session->s_leader)
                                ksignal(tp->t_session->s_leader, SIGHUP);
                        ttyflush(tp, FREAD | FWRITE);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (0);
                }
        } else {
@@ -1649,13 +1631,12 @@ ttymodem(struct tty *tp, int flag)
                ttwakeup(tp);
                ttwwakeup(tp);
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (1);
 }
 
 /*
  * Reinput pending characters after state switch
- * call from a critical section.
  */
 static void
 ttypend(struct tty *tp)
@@ -1663,7 +1644,7 @@ ttypend(struct tty *tp)
        struct clist tq;
        int c;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        CLR(tp->t_lflag, PENDIN);
        SET(tp->t_state, TS_TYPEN);
        /*
@@ -1679,7 +1660,7 @@ ttypend(struct tty *tp)
        while ((c = clist_getc(&tq)) >= 0)
                ttyinput(c, tp);
        CLR(tp->t_state, TS_TYPEN);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*
@@ -1703,9 +1684,8 @@ ttread(struct tty *tp, struct uio *uio, int flag)
        stime.tv_sec = 0;       /* fix compiler warnings */
        stime.tv_usec = 0;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
 loop:
-       crit_enter();
        lflag = tp->t_lflag;
        /*
         * take pending input first
@@ -1722,19 +1702,18 @@ loop:
        if ((pp = curproc) != NULL)
                lwkt_gettoken(&pp->p_token);
        if (pp && isbackground(pp, tp)) {
-               crit_exit();
                if (SIGISMEMBER(pp->p_sigignore, SIGTTIN) ||
                    SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
                    (pp->p_flags & P_PPWAIT) || pp->p_pgrp->pg_jobc == 0) {
                        lwkt_reltoken(&pp->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (EIO);
                }
                pgsignal(pp->p_pgrp, SIGTTIN, 1);
                error = ttysleep(tp, &lbolt, PCATCH, "ttybg2", 0);
                if (error) {
                        lwkt_reltoken(&pp->p_token);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (error);
                }
                lwkt_reltoken(&pp->p_token);
@@ -1744,8 +1723,7 @@ loop:
                lwkt_reltoken(&pp->p_token);
 
        if (ISSET(tp->t_state, TS_ZOMBIE)) {
-               crit_exit();
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (0);     /* EOF */
        }
 
@@ -1761,12 +1739,10 @@ loop:
                if (qp->c_cc > 0)
                        goto read;
                if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
-                       crit_exit();
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (0);
                }
-               crit_exit();
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (EWOULDBLOCK);
        }
        if (!ISSET(lflag, ICANON)) {
@@ -1789,8 +1765,7 @@ loop:
                                goto read;
 
                        /* m, t and qp->c_cc are all 0.  0 is enough input. */
-                       crit_exit();
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (0);
                }
                t *= 100000;            /* time in us */
@@ -1830,8 +1805,7 @@ loop:
                                slp = t - diff(timecopy, stime);
                                if (slp <= 0) {
                                        /* Timed out, but 0 is enough input. */
-                                       crit_exit();
-                                       lwkt_reltoken(&tty_token);
+                                       lwkt_reltoken(&tp->t_token);
                                        return (0);
                                }
                        }
@@ -1857,11 +1831,10 @@ sleep:
                error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), PCATCH,
                                 ISSET(tp->t_state, TS_CONNECTED) ?
                                 "ttyin" : "ttyhup", (int)slp);
-               crit_exit();
                if (error == EWOULDBLOCK)
                        error = 0;
                else if (error) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (error);
                }
                /*
@@ -1874,7 +1847,6 @@ sleep:
                goto loop;
        }
 read:
-       crit_exit();
        /*
         * Input present, check for input mapping and processing.
         */
@@ -1955,13 +1927,12 @@ out:
         * Look to unblock input now that (presumably)
         * the input queue has gone down.
         */
-       crit_enter();
        if (ISSET(tp->t_state, TS_TBLOCK) &&
-           tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat)
+           tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat) {
                ttyunblock(tp);
-       crit_exit();
+       }
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (error);
 }
 
@@ -1979,11 +1950,10 @@ ttycheckoutq(struct tty *tp, int wait)
        int hiwat;
        sigset_t oldset, newset;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        hiwat = tp->t_ohiwat;
        SIGEMPTYSET(oldset);
        SIGEMPTYSET(newset);
-       crit_enter();
        if (wait)
                oldset = lwp_sigpend(lp);
        if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100) {
@@ -1994,16 +1964,14 @@ ttycheckoutq(struct tty *tp, int wait)
                        if (wait)
                                newset = lwp_sigpend(lp);
                        if (!wait || SIGSETNEQ(oldset, newset)) {
-                               crit_exit();
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
                                return (0);
                        }
                        SET(tp->t_state, TS_SO_OLOWAT);
                        tsleep(TSA_OLOWAT(tp), 0, "ttoutq", hz);
                }
        }
-       crit_exit();
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (1);
 }
 
@@ -2022,33 +1990,28 @@ ttwrite(struct tty *tp, struct uio *uio, int flag)
 
        char obuf[OBUFSIZ];
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        lp = curthread->td_lwp;
        hiwat = tp->t_ohiwat;
        cnt = uio->uio_resid;
        error = 0;
        cc = 0;
 loop:
-       crit_enter();
        if (ISSET(tp->t_state, TS_ZOMBIE)) {
-               crit_exit();
                if (uio->uio_resid == cnt)
                        error = EIO;
                goto out;
        }
        if (!ISSET(tp->t_state, TS_CONNECTED)) {
                if (flag & IO_NDELAY) {
-                       crit_exit();
                        error = EWOULDBLOCK;
                        goto out;
                }
                error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "ttydcd", 0);
-               crit_exit();
                if (error)
                        goto out;
                goto loop;
        }
-       crit_exit();
 
        /*
         * Hang the process if it's in the background.
@@ -2081,7 +2044,7 @@ loop:
        while (uio->uio_resid > 0 || cc > 0) {
                if (ISSET(tp->t_lflag, FLUSHO)) {
                        uio->uio_resid = 0;
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
                        return (0);
                }
                if (tp->t_outq.c_cc > hiwat)
@@ -2182,29 +2145,25 @@ out:
         * (the call will either return short or restart with a new uio).
         */
        uio->uio_resid += cc;
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
        return (error);
 
 ovhiwat:
        ttstart(tp);
-       crit_enter();
        /*
         * This can only occur if FLUSHO is set in t_lflag,
         * or if ttstart/oproc is synchronous (or very fast).
         */
        if (tp->t_outq.c_cc <= hiwat) {
-               crit_exit();
                goto loop;
        }
        if (flag & IO_NDELAY) {
-               crit_exit();
                uio->uio_resid += cc;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
        }
        SET(tp->t_state, TS_SO_OLOWAT);
        error = ttysleep(tp, TSA_OLOWAT(tp), PCATCH, "ttywri", tp->t_timeout);
-       crit_exit();
        if (error == EWOULDBLOCK)
                error = EIO;
        if (error)
@@ -2215,7 +2174,7 @@ ovhiwat:
 /*
  * Rubout one character from the rawq of tp
  * as cleanly as possible.
- * NOTE: Must be called with tty_token held
+ * NOTE: Must be called with tp->t_token held
  */
 static void
 ttyrub(int c, struct tty *tp)
@@ -2224,7 +2183,7 @@ ttyrub(int c, struct tty *tp)
        int savecol;
        int tabc;
 
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
+       ASSERT_LWKT_TOKEN_HELD(&tp->t_token);
        if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
                return;
        CLR(tp->t_lflag, FLUSHO);
@@ -2257,7 +2216,6 @@ ttyrub(int c, struct tty *tp)
                                        ttyretype(tp);
                                        return;
                                }
-                               crit_enter();
                                savecol = tp->t_column;
                                SET(tp->t_state, TS_CNTTB);
                                SET(tp->t_lflag, FLUSHO);
@@ -2269,7 +2227,6 @@ ttyrub(int c, struct tty *tp)
                                        ttyecho(tabc, tp);
                                CLR(tp->t_lflag, FLUSHO);
                                CLR(tp->t_state, TS_CNTTB);
-                               crit_exit();
 
                                /* savecol will now be length of the tab. */
                                savecol -= tp->t_column;
@@ -2309,12 +2266,12 @@ ttyrub(int c, struct tty *tp)
 
 /*
  * Back over cnt characters, erasing them.
- * NOTE: Must be called with tty_token held
+ * NOTE: Must be called with tp->t_token held
  */
 static void
 ttyrubo(struct tty *tp, int cnt)
 {
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
+       ASSERT_LWKT_TOKEN_HELD(&tp->t_token);
        while (cnt-- > 0) {
                (void)ttyoutput('\b', tp);
                (void)ttyoutput(' ', tp);
@@ -2326,7 +2283,7 @@ ttyrubo(struct tty *tp, int cnt)
  * ttyretype --
  *     Reprint the rawq line.  Note, it is assumed that c_cc has already
  *     been checked.
- * NOTE: Must be called with tty_token held
+ * NOTE: Must be called with tp->t_token held
  */
 static void
 ttyretype(struct tty *tp)
@@ -2334,7 +2291,7 @@ ttyretype(struct tty *tp)
        char *cp;
        int c;
 
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
+       ASSERT_LWKT_TOKEN_HELD(&tp->t_token);
        /* Echo the reprint character. */
        if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
                ttyecho(tp->t_cc[VREPRINT], tp);
@@ -2346,7 +2303,6 @@ ttyretype(struct tty *tp)
         * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
         * BIT OF FIRST CHAR.
         */
-       crit_enter();
        for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
            cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
                ttyecho(c, tp);
@@ -2354,7 +2310,6 @@ ttyretype(struct tty *tp)
            cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
                ttyecho(c, tp);
        CLR(tp->t_state, TS_ERASE);
-       crit_exit();
 
        tp->t_rocount = tp->t_rawq.c_cc;
        tp->t_rocol = 0;
@@ -2362,12 +2317,12 @@ ttyretype(struct tty *tp)
 
 /*
  * Echo a typed character to the terminal.
- * NOTE: Must be called with tty_token held
+ * NOTE: Must be called with tp->t_token held
  */
 static void
 ttyecho(int c, struct tty *tp)
 {
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
+       ASSERT_LWKT_TOKEN_HELD(&tp->t_token);
 
        if (!ISSET(tp->t_state, TS_CNTTB))
                CLR(tp->t_lflag, FLUSHO);
@@ -2394,12 +2349,12 @@ ttyecho(int c, struct tty *tp)
 void
 ttwakeup(struct tty *tp)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
                pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
        wakeup(TSA_HUP_OR_INPUT(tp));
        KNOTE(&tp->t_rkq.ki_note, 0);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*
@@ -2408,7 +2363,7 @@ ttwakeup(struct tty *tp)
 void
 ttwwakeup(struct tty *tp)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
                pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
        if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
@@ -2422,7 +2377,7 @@ ttwwakeup(struct tty *tp)
                wakeup(TSA_OLOWAT(tp));
        }
        KNOTE(&tp->t_wkq.ki_note, 0);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*
@@ -2453,7 +2408,7 @@ ttsetwater(struct tty *tp)
 {
        int cps, ttmaxhiwat, x;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        /* Input. */
        clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
        switch (tp->t_ispeedwat) {
@@ -2502,7 +2457,7 @@ ttsetwater(struct tty *tp)
        x += OBUFSIZ + 100;
        clist_alloc_cblocks(&tp->t_outq, x, x);
 #undef CLAMP
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*
@@ -2525,7 +2480,7 @@ ttyinfo(struct tty *tp)
        if (ttycheckoutq(tp,0) == 0)
                return;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
 
        /*
         * We always print the load average, then figure out what else to
@@ -2545,8 +2500,7 @@ ttyinfo(struct tty *tp)
 
        /*
         * Pick an interesting process.  Note that certain elements,
-        * in particular the wmesg, require a critical section for
-        * safe access (YYY and we are still not MP safe).
+        * in particular the wmesg.
         *
         * NOTE: lwp_wmesg is lwp_thread->td_wmesg.
         */
@@ -2608,8 +2562,7 @@ ttyinfo(struct tty *tp)
 
        /*
         * Calculate cpu usage, percent cpu, and cmsz.  Note that
-        * 'pick' becomes invalid the moment we exit the critical
-        * section.
+        * 'pick' becomes invalid the moment we release the token.
         */
        if (lp->lwp_thread && (pick->p_flags & P_SWAPPEDOUT) == 0)
                calcru_proc(pick, &ru);
@@ -2651,7 +2604,7 @@ done1:
        pgrel(pgrp);
 done2:
        tp->t_rocount = 0;      /* so pending input will be retyped if BS */
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 }
 
 /*
@@ -2784,19 +2737,17 @@ done:
 int
 tputchar(int c, struct tty *tp)
 {
-       crit_enter();
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        if (!ISSET(tp->t_state, TS_CONNECTED)) {
-               lwkt_reltoken(&tty_token);
-               crit_exit();
+               lwkt_reltoken(&tp->t_token);
                return (-1);
        }
        if (c == '\n')
                (void)ttyoutput('\r', tp);
        (void)ttyoutput(c, tp);
        ttstart(tp);
-       lwkt_reltoken(&tty_token);
-       crit_exit();
+       lwkt_reltoken(&tp->t_token);
+
        return (0);
 }
 
@@ -2832,50 +2783,75 @@ ttyrevoke(struct dev_revoke_args *ap)
 {
        struct tty *tp;
 
-       lwkt_gettoken(&tty_token);
        tp = ap->a_head.a_dev->si_tty;
+       lwkt_gettoken(&tp->t_token);
        tp->t_gen++;
        ttyflush(tp, FREAD | FWRITE);
        wakeup(TSA_CARR_ON(tp));
        ttwakeup(tp);
        ttwwakeup(tp);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+
        return (0);
 }
 
 /*
  * Allocate a tty struct.  Clists in the struct will be allocated by
- * ttyopen().
+ * ttyopen().  The tty itself is protected by tp->t_token.  tty_token
+ * is primarily used to interlock the NULL test and for registration.
+ *
+ * by convention, once allocated, tty structures are never freed.  This
+ * saves us from numerous release race scenarios that can occur due to the
+ * token being embedded in the tty structure.
  */
 struct tty *
-ttymalloc(struct tty *tp)
+ttymalloc(struct tty **tpp)
 {
+       struct tty *tp;
 
-       if (tp) {
-               return(tp);
+       if ((tp = *tpp) == NULL) {
+               tp = kmalloc(sizeof *tp, M_TTYS, M_WAITOK|M_ZERO);
+               lwkt_gettoken(&tty_token);
+               if (*tpp == NULL) {     /* recheck after blocking kmalloc */
+                       *tpp = tp;
+                       ttyinit(tp);
+                       ttyregister(tp);
+               } else {
+                       kfree(tp, M_TTYS);
+               }
+               lwkt_reltoken(&tty_token);
        }
-       tp = kmalloc(sizeof *tp, M_TTYS, M_WAITOK|M_ZERO);
-       ttyregister(tp);
         return (tp);
 }
 
+/*
+ * Caller must hold tp->t_token
+ */
 void
 ttyunregister(struct tty *tp)
 {
        lwkt_gettoken(&tty_token);
-       KKASSERT(ISSET(tp->t_state, TS_REGISTERED));
-       CLR(tp->t_state, TS_REGISTERED);
-       TAILQ_REMOVE(&tty_list, tp, t_list);
+       if (ISSET(tp->t_state, TS_REGISTERED)) {
+               CLR(tp->t_state, TS_REGISTERED);
+               TAILQ_REMOVE(&tty_list, tp, t_list);
+       }
        lwkt_reltoken(&tty_token);
 }
 
+void
+ttyinit(struct tty *tp)
+{
+       lwkt_token_init(&tp->t_token, "tp");
+}
+
 void
 ttyregister(struct tty *tp)
 {
        lwkt_gettoken(&tty_token);
-       KKASSERT(!ISSET(tp->t_state, TS_REGISTERED));
-       SET(tp->t_state, TS_REGISTERED);
-       TAILQ_INSERT_HEAD(&tty_list, tp, t_list);
+       if (!ISSET(tp->t_state, TS_REGISTERED)) {
+               SET(tp->t_state, TS_REGISTERED);
+               TAILQ_INSERT_HEAD(&tty_list, tp, t_list);
+       }
        lwkt_reltoken(&tty_token);
 }
 
@@ -2929,9 +2905,9 @@ ttyread(struct dev_read_args *ap)
        tp = ap->a_head.a_dev->si_tty;
        if (tp == NULL)
                return (ENODEV);
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        ret = ((*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag));
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 
        return ret;
 }
@@ -2945,9 +2921,9 @@ ttywrite(struct dev_write_args *ap)
        tp = ap->a_head.a_dev->si_tty;
        if (tp == NULL)
                return (ENODEV);
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&tp->t_token);
        ret = ((*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag));
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
 
        return ret;
 }
index 745bb21..34fd21c 100644 (file)
@@ -149,6 +149,7 @@ cninit(void)
         * its init.
         */
        lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&vga_token);
 
        /*
         * Check if we should mute the console (for security reasons perhaps)
@@ -204,6 +205,7 @@ done:
         * Also assert that the mpcount is still correct or otherwise
         * the SMP/AP boot will blow up on us.
         */
+       lwkt_reltoken(&vga_token);
        lwkt_reltoken(&tty_token);
 }
 
index c0b05dc..a0378fa 100644 (file)
  */
 
 /*
- * MPSAFE NOTE: 
  * Most functions here could use a separate lock to deal with concurrent
  * access to the 'pt's.
- *
- * Right now the tty_token must be held for all this.
  */
 
 /*
@@ -87,6 +84,7 @@ static        d_write_t       ptcwrite;
 static d_kqfilter_t    ptckqfilter;
 
 DEVFS_DEFINE_CLONE_BITMAP(pty);
+static struct pt_ioctl **ptis;         /* keep pti's intact */
 
 static d_clone_t       ptyclone;
 
@@ -137,7 +135,9 @@ static struct dev_ops ptc_ops = {
        .d_revoke =     ttyrevoke
 };
 
-#define BUFSIZ 100             /* Chunk size iomoved to/from user */
+#define BUFSIZ 100             /* Chunk size iomoved to/from user */
+
+#define MAXPTYS        1000            /* Maximum cloneable ptys */
 
 struct pt_ioctl {
        int     pt_flags;
@@ -188,67 +188,87 @@ ptyinit(int n)
 {
        cdev_t devs, devc;
        char *names = "pqrsPQRS";
-       struct pt_ioctl *pt;
+       struct pt_ioctl *pti;
 
        /* For now we only map the lower 8 bits of the minor */
        if (n & ~0xff)
                return;
 
-       pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
-       pt->devs = devs = make_dev(&pts_ops, n,
-           0, 0, 0666, "tty%c%c", names[n / 32], hex2ascii(n % 32));
-       pt->devc = devc = make_dev(&ptc_ops, n,
-           0, 0, 0666, "pty%c%c", names[n / 32], hex2ascii(n % 32));
-
-       pt->pt_tty.t_dev = devs;
-       pt->pt_uminor = n;
-       devs->si_drv1 = devc->si_drv1 = pt;
-       devs->si_tty = devc->si_tty = &pt->pt_tty;
+       pti = kmalloc(sizeof(*pti), M_PTY, M_WAITOK | M_ZERO);
+       pti->devs = devs = make_dev(&pts_ops, n, 0, 0, 0666,
+                                   "tty%c%c",
+                                   names[n / 32], hex2ascii(n % 32));
+       pti->devc = devc = make_dev(&ptc_ops, n, 0, 0, 0666,
+                                   "pty%c%c",
+                                   names[n / 32], hex2ascii(n % 32));
+
+       pti->pt_tty.t_dev = devs;
+       pti->pt_uminor = n;
+       devs->si_drv1 = devc->si_drv1 = pti;
+       devs->si_tty = devc->si_tty = &pti->pt_tty;
        devs->si_flags |= SI_OVERRIDE;  /* uid, gid, perms from dev */
        devc->si_flags |= SI_OVERRIDE;  /* uid, gid, perms from dev */
-       ttyregister(&pt->pt_tty);
+       ttyinit(&pti->pt_tty);
+       ttyregister(&pti->pt_tty);
 }
 
 static int
 ptyclone(struct dev_clone_args *ap)
 {
        int unit;
-       struct pt_ioctl *pt;
+       struct pt_ioctl *pti;
 
        /*
         * Limit the number of unix98 pty (slave) devices to 1000, as
         * the utmp(5) format only allows for 8 bytes for the tty,
         * "pts/XXX".
-        * If this limit is reached, we don't clone and return error
+        *
+        * If this limit is reached, we don't clone and return an error
         * to devfs.
         */
-       unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(pty), 1000);
+       unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(pty), MAXPTYS);
 
        if (unit < 0) {
                ap->a_dev = NULL;
                return 1;
        }
 
-       pt = kmalloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
-
-       pt->devc = make_only_dev(&ptc98_ops, unit,
-                                ap->a_cred->cr_ruid,
-                                0, 0600, "ptm/%d", unit);
-       pt->devs = make_dev(&pts98_ops, unit,
-                           ap->a_cred->cr_ruid,
-                           GID_TTY, 0620, "pts/%d", unit);
-       ap->a_dev = pt->devc;
-
-       pt->devs->si_flags |= SI_OVERRIDE;      /* uid, gid, perms from dev */
-       pt->devc->si_flags |= SI_OVERRIDE;      /* uid, gid, perms from dev */
-
-       pt->pt_tty.t_dev = pt->devs;
-       pt->pt_flags |= PF_UNIX98;
-       pt->pt_uminor = unit;
-       pt->devs->si_drv1 = pt->devc->si_drv1 = pt;
-       pt->devs->si_tty = pt->devc->si_tty = &pt->pt_tty;
+       /*
+        * pti structures must be persistent once allocated.
+        */
+       if ((pti = ptis[unit]) == NULL) {
+               lwkt_gettoken(&tty_token);
+               pti = kmalloc(sizeof(*pti), M_PTY, M_WAITOK | M_ZERO);
+               if (ptis[unit] == NULL) {
+                       ptis[unit] = pti;
+                       ttyinit(&pti->pt_tty);
+               } else {
+                       kfree(pti, M_PTY);
+               }
+               lwkt_reltoken(&tty_token);
+       }
 
-       ttyregister(&pt->pt_tty);
+       /*
+        * The cloning bitmap should guarantee isolation during
+        * initialization.
+        */
+       pti->devc = make_only_dev(&ptc98_ops, unit,
+                                 ap->a_cred->cr_ruid,
+                                 0, 0600, "ptm/%d", unit);
+       pti->devs = make_dev(&pts98_ops, unit,
+                            ap->a_cred->cr_ruid,
+                            GID_TTY, 0620, "pts/%d", unit);
+       ap->a_dev = pti->devc;
+
+       pti->devs->si_flags |= SI_OVERRIDE;     /* uid, gid, perms from dev */
+       pti->devc->si_flags |= SI_OVERRIDE;     /* uid, gid, perms from dev */
+
+       pti->pt_tty.t_dev = pti->devs;
+       pti->pt_flags = PF_UNIX98;
+       pti->pt_uminor = unit;
+       pti->devs->si_drv1 = pti->devc->si_drv1 = pti;
+       pti->devs->si_tty = pti->devc->si_tty = &pti->pt_tty;
+       ttyregister(&pti->pt_tty);
 
        return 0;
 }
@@ -259,8 +279,6 @@ ptyclone(struct dev_clone_args *ap)
  *
  * This function returns non-zero if we cannot hold due to a termination
  * interlock.
- *
- * NOTE: Must be called with tty_token held
  */
 static int
 pti_hold(struct pt_ioctl *pti)
@@ -268,6 +286,7 @@ pti_hold(struct pt_ioctl *pti)
        if (pti->pt_flags & PF_TERMINATED)
                return(ENXIO);
        ++pti->pt_refs;
+
        return(0);
 }
 
@@ -282,16 +301,17 @@ pti_hold(struct pt_ioctl *pti)
 static void
 pti_done(struct pt_ioctl *pti)
 {
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&pti->pt_tty.t_token);
        if (--pti->pt_refs == 0) {
                cdev_t dev;
                int uminor_no;
 
                /*
-                * Only unix09 ptys are freed up
+                * Only unix09 ptys are freed up (the pti structure itself
+                * is never freed, regardless).
                 */
                if ((pti->pt_flags & PF_UNIX98) == 0) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&pti->pt_tty.t_token);
                        return;
                }
 
@@ -319,12 +339,14 @@ pti_done(struct pt_ioctl *pti)
                                destroy_dev(dev);
                        }
                        ttyunregister(&pti->pt_tty);
+                       pti->pt_tty.t_dev = NULL;
+
                        devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty),
                                               uminor_no);
-                       kfree(pti, M_PTY);
+                       /* pti structure remains intact */
                }
        }
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&pti->pt_tty.t_token);
 }
 
 /*ARGSUSED*/
@@ -345,9 +367,9 @@ ptsopen(struct dev_open_args *ap)
                return(ENXIO);
        pti = dev->si_drv1;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&pti->pt_tty.t_token);
        if (pti_hold(pti)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return(ENXIO);
        }
 
@@ -367,11 +389,11 @@ ptsopen(struct dev_open_args *ap)
        } else if ((tp->t_state & TS_XCLUDE) &&
                   priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) {
                pti_done(pti);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return (EBUSY);
        } else if (pti->pt_prison != ap->a_cred->cr_prison) {
                pti_done(pti);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return (EBUSY);
        }
 
@@ -396,7 +418,7 @@ ptsopen(struct dev_open_args *ap)
                error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "ptsopn", 0);
                if (error) {
                        pti_done(pti);
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&pti->pt_tty.t_token);
                        return (error);
                }
        }
@@ -412,8 +434,8 @@ ptsopen(struct dev_open_args *ap)
                ptcwakeup(tp, FREAD|FWRITE);
        }
        pti_done(pti);
+       lwkt_reltoken(&pti->pt_tty.t_token);
 
-       lwkt_reltoken(&tty_token);
        return (error);
 }
 
@@ -425,7 +447,7 @@ ptsclose(struct dev_close_args *ap)
        struct pt_ioctl *pti = dev->si_drv1;
        int err;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&pti->pt_tty.t_token);
        if (pti_hold(pti))
                panic("ptsclose on terminated pti");
 
@@ -451,7 +473,7 @@ ptsclose(struct dev_close_args *ap)
        if (tp->t_oproc)
                ptcwakeup(tp, FREAD);
        pti_done(pti);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&pti->pt_tty.t_token);
        return (err);
 }
 
@@ -468,7 +490,7 @@ ptsread(struct dev_read_args *ap)
 
        lp = curthread->td_lwp;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&pti->pt_tty.t_token);
 again:
        if (pti->pt_flags & PF_REMOTE) {
                while (isbackground(p, tp)) {
@@ -476,25 +498,25 @@ again:
                            SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
                            p->p_pgrp->pg_jobc == 0 ||
                            (p->p_flags & P_PPWAIT)) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&pti->pt_tty.t_token);
                                return (EIO);
                        }
                        pgsignal(p->p_pgrp, SIGTTIN, 1);
                        error = ttysleep(tp, &lbolt, PCATCH, "ptsbg", 0);
                        if (error) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&pti->pt_tty.t_token);
                                return (error);
                        }
                }
                if (tp->t_canq.c_cc == 0) {
                        if (ap->a_ioflag & IO_NDELAY) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&pti->pt_tty.t_token);
                                return (EWOULDBLOCK);
                        }
                        error = ttysleep(tp, TSA_PTS_READ(tp), PCATCH,
                                         "ptsin", 0);
                        if (error) {
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&pti->pt_tty.t_token);
                                return (error);
                        }
                        goto again;
@@ -507,14 +529,15 @@ again:
                if (tp->t_canq.c_cc == 1)
                        clist_getc(&tp->t_canq);
                if (tp->t_canq.c_cc) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&pti->pt_tty.t_token);
                        return (error);
                }
        } else
                if (tp->t_oproc)
                        error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag);
        ptcwakeup(tp, FWRITE);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&pti->pt_tty.t_token);
+
        return (error);
 }
 
@@ -530,14 +553,15 @@ ptswrite(struct dev_write_args *ap)
        struct tty *tp;
        int ret;
 
-       lwkt_gettoken(&tty_token);
        tp = dev->si_tty;
+       lwkt_gettoken(&tp->t_token);
        if (tp->t_oproc == NULL) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
                return (EIO);
        }
        ret = ((*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag));
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+
        return ret;
 }
 
@@ -548,11 +572,13 @@ ptswrite(struct dev_write_args *ap)
 static void
 ptsstart(struct tty *tp)
 {
-       lwkt_gettoken(&tty_token);
        struct pt_ioctl *pti = tp->t_dev->si_drv1;
 
+       lwkt_gettoken(&pti->pt_tty.t_token);
+       lwkt_gettoken(&tp->t_token);
        if (tp->t_state & TS_TTSTOP) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return;
        }
        if (pti) {
@@ -562,17 +588,16 @@ ptsstart(struct tty *tp)
                }
        }
        ptcwakeup(tp, FREAD);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+       lwkt_reltoken(&pti->pt_tty.t_token);
 }
 
 /*
- * NOTE: Must be called with tty_token held
+ * NOTE: Must be called with tp->t_token held
  */
 static void
 ptcwakeup(struct tty *tp, int flag)
 {
-       ASSERT_LWKT_TOKEN_HELD(&tty_token);
-
        if (flag & FREAD) {
                wakeup(TSA_PTC_READ(tp));
                KNOTE(&tp->t_rkq.ki_note, 0);
@@ -595,24 +620,26 @@ ptcopen(struct dev_open_args *ap)
         * pre-created if a non-unix 98 pty.  If si_drv1 is NULL
         * we are somehow racing a unix98 termination.
         */
-       if (dev->si_drv1 == NULL)
+       pti = dev->si_drv1;
+       if (pti == NULL)
                return(ENXIO);
 
-       lwkt_gettoken(&tty_token);
-       pti = dev->si_drv1;
+       lwkt_gettoken(&pti->pt_tty.t_token);
        if (pti_hold(pti)) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return(ENXIO);
        }
        if (pti->pt_prison && pti->pt_prison != ap->a_cred->cr_prison) {
                pti_done(pti);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return(EBUSY);
        }
        tp = dev->si_tty;
+       lwkt_gettoken(&tp->t_token);
        if (tp->t_oproc) {
                pti_done(pti);
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return (EIO);
        }
 
@@ -652,7 +679,9 @@ ptcopen(struct dev_open_args *ap)
        pti->pt_flags |= PF_MOPEN;
        pti_done(pti);
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+       lwkt_reltoken(&pti->pt_tty.t_token);
+
        return (0);
 }
 
@@ -663,11 +692,14 @@ ptcclose(struct dev_close_args *ap)
        struct tty *tp;
        struct pt_ioctl *pti = dev->si_drv1;
 
-       lwkt_gettoken(&tty_token);
-       if (pti_hold(pti))
+       lwkt_gettoken(&pti->pt_tty.t_token);
+       if (pti_hold(pti)) {
+               lwkt_reltoken(&pti->pt_tty.t_token);
                panic("ptcclose on terminated pti");
-
+       }
        tp = dev->si_tty;
+       lwkt_gettoken(&tp->t_token);
+
        (void)(*linesw[tp->t_line].l_modem)(tp, 0);
 
        /*
@@ -702,8 +734,9 @@ ptcclose(struct dev_close_args *ap)
        pti->devc->si_perms = 0666;
 
        pti_done(pti);
+       lwkt_reltoken(&tp->t_token);
+       lwkt_reltoken(&pti->pt_tty.t_token);
 
-       lwkt_reltoken(&tty_token);
        return (0);
 }
 
@@ -716,7 +749,9 @@ ptcread(struct dev_read_args *ap)
        char buf[BUFSIZ];
        int error = 0, cc;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&pti->pt_tty.t_token);
+       lwkt_gettoken(&tp->t_token);
+
        /*
         * We want to block until the slave
         * is open, and there's something to read;
@@ -728,7 +763,8 @@ ptcread(struct dev_read_args *ap)
                        if ((pti->pt_flags & PF_PKT) && pti->pt_send) {
                                error = ureadc((int)pti->pt_send, ap->a_uio);
                                if (error) {
-                                       lwkt_reltoken(&tty_token);
+                                       lwkt_reltoken(&tp->t_token);
+                                       lwkt_reltoken(&pti->pt_tty.t_token);
                                        return (error);
                                }
                                if (pti->pt_send & TIOCPKT_IOCTL) {
@@ -738,33 +774,41 @@ ptcread(struct dev_read_args *ap)
                                                ap->a_uio);
                                }
                                pti->pt_send = 0;
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
+                               lwkt_reltoken(&pti->pt_tty.t_token);
+
                                return (0);
                        }
                        if ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl) {
                                error = ureadc((int)pti->pt_ucntl, ap->a_uio);
                                if (error) {
-                                       lwkt_reltoken(&tty_token);
+                                       lwkt_reltoken(&tp->t_token);
+                                       lwkt_reltoken(&pti->pt_tty.t_token);
                                        return (error);
                                }
                                pti->pt_ucntl = 0;
-                               lwkt_reltoken(&tty_token);
+                               lwkt_reltoken(&tp->t_token);
+                               lwkt_reltoken(&pti->pt_tty.t_token);
+
                                return (0);
                        }
                        if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
                                break;
                }
                if ((tp->t_state & TS_CONNECTED) == 0) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
+                       lwkt_reltoken(&pti->pt_tty.t_token);
                        return (0);     /* EOF */
                }
                if (ap->a_ioflag & IO_NDELAY) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
+                       lwkt_reltoken(&pti->pt_tty.t_token);
                        return (EWOULDBLOCK);
                }
                error = tsleep(TSA_PTC_READ(tp), PCATCH, "ptcin", 0);
                if (error) {
-                       lwkt_reltoken(&tty_token);
+                       lwkt_reltoken(&tp->t_token);
+                       lwkt_reltoken(&pti->pt_tty.t_token);
                        return (error);
                }
        }
@@ -778,7 +822,9 @@ ptcread(struct dev_read_args *ap)
                error = uiomove(buf, (size_t)cc, ap->a_uio);
        }
        ttwwakeup(tp);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+       lwkt_reltoken(&pti->pt_tty.t_token);
+
        return (error);
 }
 
@@ -788,7 +834,7 @@ ptsstop(struct tty *tp, int flush)
        struct pt_ioctl *pti = tp->t_dev->si_drv1;
        int flag;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&pti->pt_tty.t_token);
        /* note: FLUSHREAD and FLUSHWRITE already ok */
        if (pti) {
                if (flush == 0) {
@@ -807,7 +853,7 @@ ptsstop(struct tty *tp, int flush)
                flag |= FREAD;
        ptcwakeup(tp, flag);
 
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&pti->pt_tty.t_token);
 }
 
 /*
@@ -821,11 +867,13 @@ ptsunhold(struct tty *tp)
 {
        struct pt_ioctl *pti = tp->t_dev->si_drv1;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&pti->pt_tty.t_token);
+       lwkt_gettoken(&tp->t_token);
        pti_hold(pti);
        --tp->t_refs;
        pti_done(pti);
-       lwkt_reltoken(&tty_token);
+       lwkt_reltoken(&tp->t_token);
+       lwkt_reltoken(&pti->pt_tty.t_token);
 }
 
 /*
@@ -870,10 +918,13 @@ filt_ptcread (struct knote *kn, long hint)
        struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
        struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&pti->pt_tty.t_token);
+       lwkt_gettoken(&tp->t_token);
+
        if ((tp->t_state & TS_ZOMBIE) || (pti->pt_flags & PF_SCLOSED)) {
-               lwkt_reltoken(&tty_token);
                kn->kn_flags |= (EV_EOF | EV_NODATA);
+               lwkt_reltoken(&tp->t_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return (1);
        }
 
@@ -882,10 +933,12 @@ filt_ptcread (struct knote *kn, long hint)
             ((pti->pt_flags & PF_PKT) && pti->pt_send) ||
             ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))) {
                kn->kn_data = tp->t_outq.c_cc;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return(1);
        } else {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return(0);
        }
 }
@@ -896,9 +949,11 @@ filt_ptcwrite (struct knote *kn, long hint)
        struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
        struct pt_ioctl *pti = ((cdev_t)kn->kn_hook)->si_drv1;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&pti->pt_tty.t_token);
+       lwkt_gettoken(&tp->t_token);
        if (tp->t_state & TS_ZOMBIE) {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                kn->kn_flags |= (EV_EOF | EV_NODATA);
                return (1);
        }
@@ -909,10 +964,12 @@ filt_ptcwrite (struct knote *kn, long hint)
             ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG - 2) ||
              (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON))))) {
                kn->kn_data = tp->t_canq.c_cc + tp->t_rawq.c_cc;
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return(1);
        } else {
-               lwkt_reltoken(&tty_token);
+               lwkt_reltoken(&tp->t_token);
+               lwkt_reltoken(&pti->pt_tty.t_token);
                return(0);
        }
        /* NOTREACHED */
@@ -949,7 +1006,8 @@ ptcwrite(struct dev_write_args *ap)
        struct pt_ioctl *pti = dev->si_drv1;
        int error = 0;
 
-       lwkt_gettoken(&tty_token);
+       lwkt_gettoken(&pti->pt_tty.t_token);
+       lwkt_gettoken(&tp->t_token);
 again:
        if ((tp->t_state&TS_ISOPEN) == 0)
                goto block;
@@ -964,14 +1022,16 @@ again:
                                cp = locbuf;
                                error = uiomove(cp, (size_t)cc, ap->a_uio);
                         &nb