Author: ray
Date: Tue Jun  3 13:33:43 2014
New Revision: 267007
URL: http://svnweb.freebsd.org/changeset/base/267007

Log:
  Fix case when vt(4) started w/o driver assigned.
  o Always init locks and cv ASAP.
  o Initialize driver-independent parts even if driver probing fail.
  o Allow to call vt_upgrade anytime, for later loaded drivers.
  o New window flag VWF_READY, to track if window already initialized.
  Other updates:
  o Pass vd as a cookie for kbd_allocate.
  o Do not blank window on driver replacement.
  
  Tested by:    hselasky (RPi), emaste(VGA, EFIFB, KMS), me
  
  MFC after:    7 days
  Sponsored by: The FreeBSD Foundation

Modified:
  head/sys/dev/vt/vt.h
  head/sys/dev/vt/vt_core.c

Modified: head/sys/dev/vt/vt.h
==============================================================================
--- head/sys/dev/vt/vt.h        Tue Jun  3 08:08:12 2014        (r267006)
+++ head/sys/dev/vt/vt.h        Tue Jun  3 13:33:43 2014        (r267007)
@@ -259,6 +259,7 @@ struct vt_window {
 #define        VWF_CONSOLE     0x8     /* Kernel message console window. */
 #define        VWF_VTYLOCK     0x10    /* Prevent window switch. */
 #define        VWF_MOUSE_HIDE  0x20    /* Disable mouse events processing. */
+#define        VWF_READY       0x40    /* Window fully initialized. */
 #define        VWF_SWWAIT_REL  0x10000 /* Program wait for VT acquire is done. 
*/
 #define        VWF_SWWAIT_ACQ  0x20000 /* Program wait for VT release is done. 
*/
        pid_t                    vw_pid;        /* Terminal holding process */

Modified: head/sys/dev/vt/vt_core.c
==============================================================================
--- head/sys/dev/vt/vt_core.c   Tue Jun  3 08:08:12 2014        (r267006)
+++ head/sys/dev/vt/vt_core.c   Tue Jun  3 13:33:43 2014        (r267007)
@@ -120,9 +120,10 @@ VT_SYSCTL_INT(debug, 0, "vt(9) debug lev
 VT_SYSCTL_INT(deadtimer, 15, "Time to wait busy process in VT_PROCESS mode");
 VT_SYSCTL_INT(suspendswitch, 1, "Switch to VT0 before suspend");
 
+static struct vt_device        vt_consdev;
 static unsigned int vt_unit = 0;
 static MALLOC_DEFINE(M_VT, "vt", "vt device");
-struct vt_device *main_vd = NULL;
+struct vt_device *main_vd = &vt_consdev;
 
 /* Boot logo. */
 extern unsigned int vt_logo_width;
@@ -214,12 +215,14 @@ static void
 vt_update_static(void *dummy)
 {
 
-       if (main_vd != NULL) {
+       if (main_vd->vd_driver != NULL)
                printf("VT: running with driver \"%s\".\n",
                    main_vd->vd_driver->vd_name);
-               mtx_init(&main_vd->vd_lock, "vtdev", NULL, MTX_DEF);
-               cv_init(&main_vd->vd_winswitch, "vtwswt");
-       }
+       else
+               printf("VT: init without driver.\n");
+
+       mtx_init(&main_vd->vd_lock, "vtdev", NULL, MTX_DEF);
+       cv_init(&main_vd->vd_winswitch, "vtwswt");
 }
 
 static void
@@ -633,11 +636,9 @@ vt_allocate_keyboard(struct vt_device *v
        keyboard_t      *k0, *k;
        keyboard_info_t  ki;
 
-       idx0 = kbd_allocate("kbdmux", -1, (void *)&vd->vd_keyboard,
-           vt_kbdevent, vd);
-       /* XXX: kb_token lost */
+       idx0 = kbd_allocate("kbdmux", -1, vd, vt_kbdevent, vd);
        vd->vd_keyboard = idx0;
-       if (idx0 != -1) {
+       if (idx0 >= 0) {
                DPRINTF(20, "%s: kbdmux allocated, idx = %d\n", __func__, idx0);
                k0 = kbd_get_keyboard(idx0);
 
@@ -657,8 +658,11 @@ vt_allocate_keyboard(struct vt_device *v
                }
        } else {
                DPRINTF(20, "%s: no kbdmux allocated\n", __func__);
-               idx0 = kbd_allocate("*", -1, (void *)&vd->vd_keyboard,
-                   vt_kbdevent, vd);
+               idx0 = kbd_allocate("*", -1, vd, vt_kbdevent, vd);
+               if (idx0 < 0) {
+                       DPRINTF(10, "%s: No keyboard found.\n", __func__);
+                       return (-1);
+               }
        }
        DPRINTF(20, "%s: vd_keyboard = %d\n", __func__, vd->vd_keyboard);
 
@@ -970,15 +974,14 @@ vtterm_cnprobe(struct terminal *tm, stru
        if (vtdbest == NULL) {
                cp->cn_pri = CN_DEAD;
                vd->vd_flags |= VDF_DEAD;
-               return;
+       } else {
+               vd->vd_driver = vtdbest;
+               cp->cn_pri = vd->vd_driver->vd_init(vd);
        }
 
-       vd->vd_driver = vtdbest;
-
-       cp->cn_pri = vd->vd_driver->vd_init(vd);
+       /* Check if driver's vt_init return CN_DEAD. */
        if (cp->cn_pri == CN_DEAD) {
                vd->vd_flags |= VDF_DEAD;
-               return;
        }
 
        /* Initialize any early-boot keyboard drivers */
@@ -988,6 +991,7 @@ vtterm_cnprobe(struct terminal *tm, stru
        vd->vd_windows[VT_CONSWINDOW] = vw;
        sprintf(cp->cn_name, "ttyv%r", VT_UNIT(vw));
 
+       /* Attach default font if not in TEXTMODE. */
        if (!(vd->vd_flags & VDF_TEXTMODE))
                vw->vw_font = vtfont_ref(&vt_font_default);
 
@@ -995,12 +999,12 @@ vtterm_cnprobe(struct terminal *tm, stru
        vt_winsize(vd, vw->vw_font, &wsz);
        terminal_set_winsize(tm, &wsz);
 
+       if (vtdbest != NULL) {
 #ifdef DEV_SPLASH
-       vtterm_splash(vd);
+               vtterm_splash(vd);
 #endif
-
-       vd->vd_flags |= VDF_INITIALIZED;
-       main_vd = vd;
+               vd->vd_flags |= VDF_INITIALIZED;
+       }
 }
 
 static int
@@ -1987,44 +1991,41 @@ vt_upgrade(struct vt_device *vd)
        struct vt_window *vw;
        unsigned int i;
 
-       /* Device didn't pass vd_init() or already upgraded. */
-       if (vd->vd_flags & (VDF_ASYNC|VDF_DEAD)) {
-               /* Refill settings with new sizes anyway. */
-               vt_resize(vd);
-               return;
-       }
-       vd->vd_flags |= VDF_ASYNC;
-
        for (i = 0; i < VT_MAXWINDOWS; i++) {
                vw = vd->vd_windows[i];
                if (vw == NULL) {
                        /* New window. */
                        vw = vt_allocate_window(vd, i);
-               } else if (vw->vw_flags & VWF_CONSOLE) {
-                       /* For existing console window. */
-                       callout_init(&vw->vw_proc_dead_timer, 0);
                }
-               if (i == VT_CONSWINDOW) {
-                       /* Console window. */
-                       EVENTHANDLER_REGISTER(shutdown_pre_sync,
-                           vt_window_switch, vw, SHUTDOWN_PRI_DEFAULT);
+               if (!(vw->vw_flags & VWF_READY)) {
+                       callout_init(&vw->vw_proc_dead_timer, 0);
+                       terminal_maketty(vw->vw_terminal, "v%r", VT_UNIT(vw));
+                       vw->vw_flags |= VWF_READY;
+                       if (vw->vw_flags & VWF_CONSOLE) {
+                               /* For existing console window. */
+                               EVENTHANDLER_REGISTER(shutdown_pre_sync,
+                                   vt_window_switch, vw, SHUTDOWN_PRI_DEFAULT);
+                       }
                }
-               terminal_maketty(vw->vw_terminal, "v%r", VT_UNIT(vw));
 
        }
        VT_LOCK(vd);
        if (vd->vd_curwindow == NULL)
                vd->vd_curwindow = vd->vd_windows[VT_CONSWINDOW];
 
+       if (!(vd->vd_flags & VDF_ASYNC)) {
        /* Attach keyboard. */
        vt_allocate_keyboard(vd);
        DPRINTF(20, "%s: vd_keyboard = %d\n", __func__, vd->vd_keyboard);
 
-       /* Init 25 Hz timer. */
-       callout_init_mtx(&vd->vd_timer, &vd->vd_lock, 0);
+               /* Init 25 Hz timer. */
+               callout_init_mtx(&vd->vd_timer, &vd->vd_lock, 0);
+
+               /* Start timer when everything ready. */
+               vd->vd_flags |= VDF_ASYNC;
+               callout_reset(&vd->vd_timer, hz / VT_TIMERFREQ, vt_timer, vd);
+       }
 
-       /* Start timer when everything ready. */
-       callout_reset(&vd->vd_timer, hz / VT_TIMERFREQ, vt_timer, vd);
        VT_UNLOCK(vd);
 
        /* Refill settings with new sizes. */
@@ -2055,13 +2056,10 @@ vt_allocate(struct vt_driver *drv, void 
        struct vt_device *vd;
        struct winsize wsz;
 
-       if (main_vd == NULL) {
-               main_vd = malloc(sizeof *vd, M_VT, M_WAITOK|M_ZERO);
+       if (main_vd->vd_driver == NULL) {
+               main_vd->vd_driver = drv;
                printf("VT: initialize with new VT driver \"%s\".\n",
                    drv->vd_name);
-               mtx_init(&main_vd->vd_lock, "vtdev", NULL, MTX_DEF);
-               cv_init(&main_vd->vd_winswitch, "vtwswt");
-
        } else {
                /*
                 * Check if have rights to replace current driver. For example:
@@ -2117,7 +2115,8 @@ vt_allocate(struct vt_driver *drv, void 
 
        /* Update console window sizes to actual. */
        vt_winsize(vd, vd->vd_windows[VT_CONSWINDOW]->vw_font, &wsz);
-       terminal_set_winsize(vd->vd_windows[VT_CONSWINDOW]->vw_terminal, &wsz);
+       terminal_set_winsize_blank(vd->vd_windows[VT_CONSWINDOW]->vw_terminal,
+           &wsz, 0);
 }
 
 void
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to