syscons(4): Use 100x37 when the VESA800X600 flag is specified.
[dragonfly.git] / sys / dev / misc / syscons / syscons.c
index 36b6c47..afdbef9 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1992-1998 Søren Schmidt
+ * Copyright (c) 1992-1998 Søren Schmidt
  * All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
@@ -129,7 +129,8 @@ SYSCTL_INT(_machdep, OID_AUTO, enable_panic_key, CTLFLAG_RW, &enable_panic_key,
        (SC_DEV((sc),(x))->si_tty) : NULL)
 #define ISTTYOPEN(tp)  ((tp) && ((tp)->t_state & TS_ISOPEN))
 
-static int             debugger;
+static int     debugger;
+static cdev_t  cctl_dev;
 
 /* prototypes */
 static int scvidprobe(int unit, int flags, int cons);
@@ -179,6 +180,7 @@ static int save_kbd_state(scr_stat *scp);
 static int update_kbd_state(scr_stat *scp, int state, int mask);
 static int update_kbd_leds(scr_stat *scp, int which);
 static timeout_t blink_screen;
+static int sc_allocate_keyboard(sc_softc_t *sc, int unit);
 
 #define        CDEV_MAJOR      12
 
@@ -209,7 +211,8 @@ static struct dev_ops sc_ops = {
        .d_ioctl =      scioctl,
        .d_poll =       ttypoll,
        .d_mmap =       scmmap,
-       .d_kqfilter =   ttykqfilter
+       .d_kqfilter =   ttykqfilter,
+       .d_revoke =     ttyrevoke
 };
 
 int
@@ -347,7 +350,7 @@ sc_attach_unit(int unit, int flags)
            splash_term(sc->adp);
 #endif
        sc_set_graphics_mode(scp, NULL, M_VESA_800x600);
-       sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
+       sc_set_pixel_mode(scp, NULL, 0, 0, 16);
        sc->initial_mode = M_VESA_800x600;
 #if NSPLASH > 0
        /* put up the splash again! */
@@ -388,28 +391,22 @@ sc_attach_unit(int unit, int flags)
                              (void *)(uintptr_t)unit, SHUTDOWN_PRI_DEFAULT);
 
     /* 
-     * create devices.  dev_ops_add() must be called to make devices under
-     * this major number available to userland.
+     * create devices.
+     *
+     * The first vty already has struct tty and scr_stat initialized
+     * in scinit().  The other vtys will have these structs when
+     * first opened.
      */
-    dev_ops_add(&sc_ops, ~(MAXCONS - 1), unit * MAXCONS);
-
-    for (vc = 0; vc < sc->vtys; vc++) {
+    for (vc = 1; vc < sc->vtys; vc++) {
        dev = make_dev(&sc_ops, vc + unit * MAXCONS,
-           UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc + unit * MAXCONS);
+                       UID_ROOT, GID_WHEEL,
+                       0600, "ttyv%r", vc + unit * MAXCONS);
        sc->dev[vc] = dev;
-       /*
-        * The first vty already has struct tty and scr_stat initialized
-        * in scinit().  The other vtys will have these structs when
-        * first opened.
-        */
     }
-
-    dev_ops_add(&sc_ops, -1, SC_CONSOLECTL);   /* XXX */
-    dev = make_dev(&sc_ops, SC_CONSOLECTL,
-                  UID_ROOT, GID_WHEEL, 0600, "consolectl");
-    dev->si_tty = sc_console_tty = ttymalloc(sc_console_tty);
-    dev->si_drv1 = sc_console;
-
+    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_drv1 = sc_console;
     return 0;
 }
 
@@ -478,7 +475,9 @@ scopen(struct dev_open_args *ap)
     tp->t_oproc = scstart;
     tp->t_param = scparam;
     tp->t_stop = nottystop;
+
     tp->t_dev = dev;
+
     if (!ISTTYOPEN(tp)) {
        ttychars(tp);
         /* Use the current setting of the <-- key as default VERASE. */  
@@ -564,6 +563,7 @@ scclose(struct dev_close_args *ap)
     (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
     ttyclose(tp);
     crit_exit();
+
     return(0);
 }
 
@@ -987,8 +987,8 @@ scioctl(struct dev_ioctl_args *ap)
        scp = SC_STAT(SC_DEV(sc, i));
        if (scp == scp->sc->cur_scp)
            return 0;
-       while ((error=tsleep((caddr_t)&scp->smode, PCATCH,
-                            "waitvt", 0)) == ERESTART) ;
+       error = tsleep((caddr_t)&scp->smode, PCATCH, "waitvt", 0);
+       /* May return ERESTART */
        return error;
 
     case VT_GETACTIVE:         /* get active vty # */
@@ -1014,7 +1014,7 @@ scioctl(struct dev_ioctl_args *ap)
            return EPERM;
 #if defined(__i386__)
        curthread->td_lwp->lwp_md.md_regs->tf_eflags |= PSL_IOPL;
-#elif defined(__amd64__)
+#elif defined(__x86_64__)
        curthread->td_lwp->lwp_md.md_regs->tf_rflags |= PSL_IOPL;
 #endif
        return 0;
@@ -1022,7 +1022,7 @@ scioctl(struct dev_ioctl_args *ap)
     case KDDISABIO:            /* disallow io operations (default) */
 #if defined(__i386__)
        curthread->td_lwp->lwp_md.md_regs->tf_eflags &= ~PSL_IOPL;
-#elif defined(__amd64__)
+#elif defined(__x86_64__)
        curthread->td_lwp->lwp_md.md_regs->tf_rflags &= ~PSL_IOPL;
 #endif
        return 0;
@@ -1121,6 +1121,13 @@ scioctl(struct dev_ioctl_args *ap)
        *(int *)data = scp->status & LED_MASK;
        return 0;
 
+       case KBADDKBD:              /* add/remove keyboard to/from mux */
+       case KBRELKBD:
+               error = kbd_ioctl(sc->kbd, cmd, data);
+               if (error == ENOIOCTL)
+                       error = ENODEV;
+               return error;
+
     case CONS_SETKBD:          /* set the new keyboard */
        {
            keyboard_t *newkbd;
@@ -1377,8 +1384,9 @@ sccninit(struct consdev *cp)
 static void
 sccninit_fini(struct consdev *cp)
 {
-    cp->cn_dev = make_dev(&sc_ops, SC_CONSOLECTL,
-                         UID_ROOT, GID_WHEEL, 0600, "consolectl");
+       if (cctl_dev == NULL)
+               kprintf("sccninit_fini: WARNING: cctl_dev is NULL!\n");
+       cp->cn_dev = cctl_dev;
 }
 
 static void
@@ -1609,8 +1617,7 @@ scrn_timer(void *arg)
     if ((sc->kbd == NULL) && (sc->config & SC_AUTODETECT_KBD)) {
        /* try to allocate a keyboard automatically */
        if (++kbd_interval >= 25) {
-           sc->keyboard = kbd_allocate("*", -1, (void *)&sc->keyboard,
-                                       sckbdevent, sc);
+           sc->keyboard = sc_allocate_keyboard(sc, -1);
            if (sc->keyboard >= 0) {
                sc->kbd = kbd_get_keyboard(sc->keyboard);
                kbd_ioctl(sc->kbd, KDSKBMODE,
@@ -2021,8 +2028,9 @@ wait_scrn_saver_stop(sc_softc_t *sc)
            break;
        }
        error = tsleep((caddr_t)&scrn_blanked, PCATCH, "scrsav", 0);
-       if ((error != 0) && (error != ERESTART))
-           break;
+       /* May return ERESTART */
+       if (error)
+               break;
     }
     run_scrn_saver = FALSE;
     return error;
@@ -2512,8 +2520,7 @@ scinit(int unit, int flags)
     sc->adapter = vid_allocate("*", unit, (void *)&sc->adapter);
     sc->adp = vid_get_adapter(sc->adapter);
     /* assert((sc->adapter >= 0) && (sc->adp != NULL)) */
-    sc->keyboard = kbd_allocate("*", unit, (void *)&sc->keyboard,
-                               sckbdevent, sc);
+    sc->keyboard = sc_allocate_keyboard(sc, unit);
     DPRINTF(1, ("sc%d: keyboard %d\n", unit, sc->keyboard));
     sc->kbd = kbd_get_keyboard(sc->keyboard);
     if (sc->kbd != NULL) {
@@ -2559,8 +2566,10 @@ scinit(int unit, int flags)
        } else {
            /* assert(sc_malloc) */
            sc->dev = kmalloc(sizeof(cdev_t)*sc->vtys, M_SYSCONS, M_WAITOK | M_ZERO);
+
            sc->dev[0] = make_dev(&sc_ops, unit*MAXCONS, UID_ROOT, 
                                GID_WHEEL, 0600, "ttyv%r", unit*MAXCONS);
+
            sc->dev[0]->si_tty = ttymalloc(sc->dev[0]->si_tty);
            scp = alloc_scp(sc, sc->first_vty);
            sc->dev[0]->si_drv1 = scp;
@@ -3463,3 +3472,41 @@ blink_screen(void *arg)
        callout_reset(&scp->blink_screen_ch, hz / 10, blink_screen, scp);
     }
 }
+
+
+/*
+ * Allocate active keyboard. Try to allocate "kbdmux" keyboard first, and,
+ * if found, add all non-busy keyboards to "kbdmux". Otherwise look for
+ * any keyboard.
+ */
+
+static int
+sc_allocate_keyboard(sc_softc_t *sc, int unit)
+{
+       int              idx0, idx;
+       keyboard_t      *k0, *k;
+       keyboard_info_t  ki;
+
+       idx0 = kbd_allocate("kbdmux", -1, (void *)&sc->keyboard, sckbdevent, sc);
+       if (idx0 != -1) {
+               k0 = kbd_get_keyboard(idx0);
+
+               for (idx = kbd_find_keyboard2("*", -1, 0, 0);
+                    idx != -1;
+                    idx = kbd_find_keyboard2("*", -1, idx + 1, 0)) {
+                       k = kbd_get_keyboard(idx);
+
+                       if (idx == idx0 || KBD_IS_BUSY(k))
+                               continue;
+
+                       bzero(&ki, sizeof(ki));
+                       strcpy(ki.kb_name, k->kb_name);
+                       ki.kb_unit = k->kb_unit;
+
+                       kbd_ioctl(k0, KBADDKBD, (caddr_t) &ki);
+               }
+       } else
+               idx0 = kbd_allocate("*", unit, (void *)&sc->keyboard, sckbdevent, sc);
+
+       return (idx0);
+}