Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Jun 2014 13:33:44 +0000 (UTC)
From:      Aleksandr Rybalko <ray@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r267007 - head/sys/dev/vt
Message-ID:  <201406031333.s53DXiIc076473@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406031333.s53DXiIc076473>