svn commit: r271769 - in stable/10/sys: dev/drm2 dev/fb dev/vt dev/vt/hw/efifb dev/vt/hw/fb dev/vt/hw/vga kern powerpc/ps3 sys

Jean-Sebastien Pedron dumbbell at FreeBSD.org
Thu Sep 18 14:38:21 UTC 2014


Author: dumbbell
Date: Thu Sep 18 14:38:18 2014
New Revision: 271769
URL: http://svnweb.freebsd.org/changeset/base/271769

Log:
  vt(4): Merge several bug fixes and improvements
  
  SVN revisions in this MFC:
    269779 270705 270706 271180 271250 271253 271682 271684
  
  Detailed commit list:
  
  r269779:
    fbd: Fix a bug where vt_fb_attach() success would be considered a failure
  
    vt_fb_attach() currently always returns 0, but it could return a code
    defined in errno.h. However, it doesn't return a CN_* code. So checking
    its return value against CN_DEAD (which is 0) is incorrect, and in this
    case, a success becomes a failure.
  
    The consequence was unimportant, because the caller (drm_fb_helper.c)
    would only log an error message in this case. The console would still
    work.
  
    Approved by:	nwhitehorn
  
  r270705:
    vt(4): Add cngrab() and cnungrab() callbacks
  
    They are used when a panic occurs or when entering a DDB session for
    instance.
  
    cngrab() forces a vt-switch to the console window, no matter if the
    original window is another terminal or an X session. However, cnungrab()
    doesn't vt-switch back to the original window currently.
  
  r270706:
    drm: Don't "taskqueue" vt-switch if under DDB/panic situation
  
    If DDB is active, we can't use a taskqueue thread to switch away from
    the X window, because this thread can't run.
  
    Reviewed by:	ray@
    Approved by:	ray@
  
  r271180:
    vt_vga: vd_setpixel_t and vd_drawrect_t are noop in text mode
  
  r271250:
    vt(4): Change the terminal and buffer sizes, even without a font
  
    This fixes a bug where scroll lock would not work for tty #0 when using
    vt_vga's textmode. The reason was that this window is created with a
    static 256x100 buffer, larger than the real size of 80x25.
  
    Now, in vt_change_font() and vt_compute_drawable_area(), we still
    perform operations even of the window has no font loaded (this is the
    case in textmode here vw->vw_font == NULL). One of these operation
    resizes the buffer accordingly.
  
    In vt_compute_drawable_area(), we take the terminal size as is (ie.
    80x25) for the drawable area.
  
    The font argument to vt_set_border() is removed (it was never used) and
    the code now uses the computed drawable area instead of re-doing its own
    calculation.
  
    Reported by:	Harald Schmalzbauer <h.schmalzbauer_omnilan.de>
    Tested by:	Harald Schmalzbauer <h.schmalzbauer_omnilan.de>
  
  r271253:
    pause_sbt(): Take the cold path (ie. use DELAY()) if KDB is active
  
    This fixes a panic in the i915 driver when one uses debug.kdb.enter=1
    under vt(4).
  
    PR:		193269
    Reported by:	emaste@
    Submitted by:	avg@
  
  r271682:
    vt(4): Fix a LOR which occurs during a call to vt_upgrade()
  
    Reported by:	kib@
    Review:		https://reviews.freebsd.org/D785
    Reviewed by:	ray@
    Approved by:	ray@
  
  r271684:
    vt(4): Use vt_fb_drawrect() and vt_fb_setpixel() in all vt_fb-derivative
  
    Review:		https://reviews.freebsd.org/D789
    Reviewed by:	nwhitehorn
    Approved by:	nwhitehorn
  
  Approved by:	re (gjb)

Modified:
  stable/10/sys/dev/drm2/drm_fb_helper.c
  stable/10/sys/dev/fb/fbd.c
  stable/10/sys/dev/vt/hw/efifb/efifb.c
  stable/10/sys/dev/vt/hw/fb/vt_early_fb.c
  stable/10/sys/dev/vt/hw/fb/vt_fb.c
  stable/10/sys/dev/vt/hw/fb/vt_fb.h
  stable/10/sys/dev/vt/hw/vga/vt_vga.c
  stable/10/sys/dev/vt/vt.h
  stable/10/sys/dev/vt/vt_core.c
  stable/10/sys/kern/kern_synch.c
  stable/10/sys/kern/subr_terminal.c
  stable/10/sys/powerpc/ps3/ps3_syscons.c
  stable/10/sys/sys/terminal.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/drm2/drm_fb_helper.c
==============================================================================
--- stable/10/sys/dev/drm2/drm_fb_helper.c	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/dev/drm2/drm_fb_helper.c	Thu Sep 18 14:38:18 2014	(r271769)
@@ -37,6 +37,9 @@ __FBSDID("$FreeBSD$");
 #include <dev/drm2/drm_crtc_helper.h>
 
 #if defined(__FreeBSD__)
+
+#include <sys/kdb.h>
+
 struct vt_kms_softc {
 	struct drm_fb_helper *fb_helper;
 	struct task	fb_mode_task;
@@ -65,7 +68,11 @@ vt_kms_postswitch(void *arg)
 	struct vt_kms_softc *sc;
 
 	sc = (struct vt_kms_softc *)arg;
-	taskqueue_enqueue_fast(taskqueue_thread, &sc->fb_mode_task);
+
+	if (!kdb_active && panicstr == NULL)
+		taskqueue_enqueue_fast(taskqueue_thread, &sc->fb_mode_task);
+	else
+		drm_fb_helper_restore_fbdev_mode(sc->fb_helper);
 
 	return (0);
 }

Modified: stable/10/sys/dev/fb/fbd.c
==============================================================================
--- stable/10/sys/dev/fb/fbd.c	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/dev/fb/fbd.c	Thu Sep 18 14:38:18 2014	(r271769)
@@ -246,8 +246,9 @@ fbd_register(struct fb_info* info)
 		return (err);
 
 	if (first) {
-		if (vt_fb_attach(info) == CN_DEAD)
-			return (ENXIO);
+		err = vt_fb_attach(info);
+		if (err)
+			return (err);
 	}
 
 	return (0);

Modified: stable/10/sys/dev/vt/hw/efifb/efifb.c
==============================================================================
--- stable/10/sys/dev/vt/hw/efifb/efifb.c	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/dev/vt/hw/efifb/efifb.c	Thu Sep 18 14:38:18 2014	(r271769)
@@ -62,6 +62,8 @@ static struct vt_driver vt_efifb_driver 
 	.vd_blank = vt_fb_blank,
 	.vd_bitblt_text = vt_fb_bitblt_text,
 	.vd_bitblt_bmp = vt_fb_bitblt_bitmap,
+	.vd_drawrect = vt_fb_drawrect,
+	.vd_setpixel = vt_fb_setpixel,
 	.vd_fb_ioctl = vt_fb_ioctl,
 	.vd_fb_mmap = vt_fb_mmap,
 	/* Better than VGA, but still generic driver. */

Modified: stable/10/sys/dev/vt/hw/fb/vt_early_fb.c
==============================================================================
--- stable/10/sys/dev/vt/hw/fb/vt_early_fb.c	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/dev/vt/hw/fb/vt_early_fb.c	Thu Sep 18 14:38:18 2014	(r271769)
@@ -61,6 +61,8 @@ static struct vt_driver vt_fb_early_driv
 	.vd_blank = vt_fb_blank,
 	.vd_bitblt_text = vt_fb_bitblt_text,
 	.vd_bitblt_bmp = vt_fb_bitblt_bitmap,
+	.vd_drawrect = vt_fb_drawrect,
+	.vd_setpixel = vt_fb_setpixel,
 	.vd_priority = VD_PRIORITY_GENERIC,
 };
 

Modified: stable/10/sys/dev/vt/hw/fb/vt_fb.c
==============================================================================
--- stable/10/sys/dev/vt/hw/fb/vt_fb.c	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/dev/vt/hw/fb/vt_fb.c	Thu Sep 18 14:38:18 2014	(r271769)
@@ -41,9 +41,6 @@ __FBSDID("$FreeBSD$");
 #include <dev/vt/hw/fb/vt_fb.h>
 #include <dev/vt/colors/vt_termcolors.h>
 
-static vd_drawrect_t	vt_fb_drawrect;
-static vd_setpixel_t	vt_fb_setpixel;
-
 static struct vt_driver vt_fb_driver = {
 	.vd_name = "fb",
 	.vd_init = vt_fb_init,
@@ -146,7 +143,7 @@ vt_fb_mmap(struct vt_device *vd, vm_ooff
 	return (EINVAL);
 }
 
-static void
+void
 vt_fb_setpixel(struct vt_device *vd, int x, int y, term_color_t color)
 {
 	struct fb_info *info;
@@ -181,7 +178,7 @@ vt_fb_setpixel(struct vt_device *vd, int
 
 }
 
-static void
+void
 vt_fb_drawrect(struct vt_device *vd, int x1, int y1, int x2, int y2, int fill,
     term_color_t color)
 {

Modified: stable/10/sys/dev/vt/hw/fb/vt_fb.h
==============================================================================
--- stable/10/sys/dev/vt/hw/fb/vt_fb.h	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/dev/vt/hw/fb/vt_fb.h	Thu Sep 18 14:38:18 2014	(r271769)
@@ -40,6 +40,8 @@ vd_init_t		vt_fb_init;
 vd_blank_t		vt_fb_blank;
 vd_bitblt_text_t	vt_fb_bitblt_text;
 vd_bitblt_bmp_t		vt_fb_bitblt_bitmap;
+vd_drawrect_t		vt_fb_drawrect;
+vd_setpixel_t		vt_fb_setpixel;
 vd_postswitch_t		vt_fb_postswitch;
 vd_fb_ioctl_t		vt_fb_ioctl;
 vd_fb_mmap_t		vt_fb_mmap;

Modified: stable/10/sys/dev/vt/hw/vga/vt_vga.c
==============================================================================
--- stable/10/sys/dev/vt/hw/vga/vt_vga.c	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/dev/vt/hw/vga/vt_vga.c	Thu Sep 18 14:38:18 2014	(r271769)
@@ -352,6 +352,9 @@ static void
 vga_setpixel(struct vt_device *vd, int x, int y, term_color_t color)
 {
 
+	if (vd->vd_flags & VDF_TEXTMODE)
+		return;
+
 	vga_bitblt_put(vd, (y * VT_VGA_WIDTH / 8) + (x / 8), color,
 	    0x80 >> (x % 8));
 }
@@ -362,6 +365,9 @@ vga_drawrect(struct vt_device *vd, int x
 {
 	int x, y;
 
+	if (vd->vd_flags & VDF_TEXTMODE)
+		return;
+
 	for (y = y1; y <= y2; y++) {
 		if (fill || (y == y1) || (y == y2)) {
 			for (x = x1; x <= x2; x++)

Modified: stable/10/sys/dev/vt/vt.h
==============================================================================
--- stable/10/sys/dev/vt/vt.h	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/dev/vt/vt.h	Thu Sep 18 14:38:18 2014	(r271769)
@@ -256,6 +256,8 @@ struct vt_window {
 	term_rect_t		 vw_draw_area;	/* (?) Drawable area. */
 	unsigned int		 vw_number;	/* (c) Window number. */
 	int			 vw_kbdmode;	/* (?) Keyboard mode. */
+	int			 vw_prev_kbdmode;/* (?) Previous mode. */
+	int			 vw_grabbed;	/* (?) Grab count. */
 	char			*vw_kbdsq;	/* Escape sequence queue*/
 	unsigned int		 vw_flags;	/* (d) Per-window flags. */
 	int			 vw_mouse_level;/* Mouse op mode. */

Modified: stable/10/sys/dev/vt/vt_core.c
==============================================================================
--- stable/10/sys/dev/vt/vt_core.c	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/dev/vt/vt_core.c	Thu Sep 18 14:38:18 2014	(r271769)
@@ -70,6 +70,9 @@ static tc_done_t	vtterm_done;
 static tc_cnprobe_t	vtterm_cnprobe;
 static tc_cngetc_t	vtterm_cngetc;
 
+static tc_cngrab_t	vtterm_cngrab;
+static tc_cnungrab_t	vtterm_cnungrab;
+
 static tc_opened_t	vtterm_opened;
 static tc_ioctl_t	vtterm_ioctl;
 static tc_mmap_t	vtterm_mmap;
@@ -86,6 +89,9 @@ const struct terminal_class vt_termclass
 	.tc_cnprobe	= vtterm_cnprobe,
 	.tc_cngetc	= vtterm_cngetc,
 
+	.tc_cngrab	= vtterm_cngrab,
+	.tc_cnungrab	= vtterm_cnungrab,
+
 	.tc_opened	= vtterm_opened,
 	.tc_ioctl	= vtterm_ioctl,
 	.tc_mmap	= vtterm_mmap,
@@ -188,6 +194,7 @@ static struct vt_window	vt_conswindow = 
 	.vw_device = &vt_consdev,
 	.vw_terminal = &vt_consterm,
 	.vw_kbdmode = K_XLATE,
+	.vw_grabbed = 0,
 };
 static struct terminal vt_consterm = {
 	.tm_class = &vt_termclass,
@@ -420,10 +427,16 @@ vt_compute_drawable_area(struct vt_windo
 	struct vt_device *vd;
 	struct vt_font *vf;
 
-	if (vw->vw_font == NULL)
+	vd = vw->vw_device;
+
+	if (vw->vw_font == NULL) {
+		vw->vw_draw_area.tr_begin.tp_col = 0;
+		vw->vw_draw_area.tr_begin.tp_row = 0;
+		vw->vw_draw_area.tr_end.tp_col = vd->vd_width;
+		vw->vw_draw_area.tr_end.tp_row = vd->vd_height;
 		return;
+	}
 
-	vd = vw->vw_device;
 	vf = vw->vw_font;
 
 	/*
@@ -1211,6 +1224,64 @@ vtterm_cngetc(struct terminal *tm)
 }
 
 static void
+vtterm_cngrab(struct terminal *tm)
+{
+	struct vt_device *vd;
+	struct vt_window *vw;
+	keyboard_t *kbd;
+
+	vw = tm->tm_softc;
+	vd = vw->vw_device;
+
+	if (!cold)
+		vt_window_switch(vw);
+
+	kbd = kbd_get_keyboard(vd->vd_keyboard);
+	if (kbd == NULL)
+		return;
+
+	if (vw->vw_grabbed++ > 0)
+		return;
+
+	/*
+	 * Make sure the keyboard is accessible even when the kbd device
+	 * driver is disabled.
+	 */
+	kbdd_enable(kbd);
+
+	/* We shall always use the keyboard in the XLATE mode here. */
+	vw->vw_prev_kbdmode = vw->vw_kbdmode;
+	vw->vw_kbdmode = K_XLATE;
+	(void)kbdd_ioctl(kbd, KDSKBMODE, (caddr_t)&vw->vw_kbdmode);
+
+	kbdd_poll(kbd, TRUE);
+}
+
+static void
+vtterm_cnungrab(struct terminal *tm)
+{
+	struct vt_device *vd;
+	struct vt_window *vw;
+	keyboard_t *kbd;
+
+	vw = tm->tm_softc;
+	vd = vw->vw_device;
+
+	kbd = kbd_get_keyboard(vd->vd_keyboard);
+	if (kbd == NULL)
+		return;
+
+	if (--vw->vw_grabbed > 0)
+		return;
+
+	kbdd_poll(kbd, FALSE);
+
+	vw->vw_kbdmode = vw->vw_prev_kbdmode;
+	(void)kbdd_ioctl(kbd, KDSKBMODE, (caddr_t)&vw->vw_kbdmode);
+	kbdd_disable(kbd);
+}
+
+static void
 vtterm_opened(struct terminal *tm, int opened)
 {
 	struct vt_window *vw = tm->tm_softc;
@@ -1228,30 +1299,40 @@ vtterm_opened(struct terminal *tm, int o
 }
 
 static int
-vt_set_border(struct vt_window *vw, struct vt_font *vf, term_color_t c)
+vt_set_border(struct vt_window *vw, term_color_t c)
 {
 	struct vt_device *vd = vw->vw_device;
-	int x, y, off_x, off_y;
 
 	if (vd->vd_driver->vd_drawrect == NULL)
 		return (ENOTSUP);
 
-	x = vd->vd_width - 1;
-	y = vd->vd_height - 1;
-	off_x = vw->vw_draw_area.tr_begin.tp_col;
-	off_y = vw->vw_draw_area.tr_begin.tp_row;
-
 	/* Top bar. */
-	if (off_y > 0)
-		vd->vd_driver->vd_drawrect(vd, 0, 0, x, off_y - 1, 1, c);
+	if (vw->vw_draw_area.tr_begin.tp_row > 0)
+		vd->vd_driver->vd_drawrect(vd,
+		    0, 0,
+		    vd->vd_width - 1, vw->vw_draw_area.tr_begin.tp_row - 1,
+		    1, c);
+
 	/* Left bar. */
-	if (off_x > 0)
-		vd->vd_driver->vd_drawrect(vd, 0, off_y, off_x - 1, y - off_y,
+	if (vw->vw_draw_area.tr_begin.tp_col > 0)
+		vd->vd_driver->vd_drawrect(vd,
+		    0, 0,
+		    vw->vw_draw_area.tr_begin.tp_col - 1, vd->vd_height - 1,
+		    1, c);
+
+	/* Right bar. */
+	if (vw->vw_draw_area.tr_end.tp_col < vd->vd_width)
+		vd->vd_driver->vd_drawrect(vd,
+		    vw->vw_draw_area.tr_end.tp_col - 1, 0,
+		    vd->vd_width - 1, vd->vd_height - 1,
+		    1, c);
+
+	/* Bottom bar. */
+	if (vw->vw_draw_area.tr_end.tp_row < vd->vd_height)
+		vd->vd_driver->vd_drawrect(vd,
+		    0, vw->vw_draw_area.tr_end.tp_row - 1,
+		    vd->vd_width - 1, vd->vd_height - 1,
 		    1, c);
-	/* Right bar.  May be 1 pixel wider than necessary due to rounding. */
-	vd->vd_driver->vd_drawrect(vd, x - off_x, off_y, x, y - off_y, 1, c);
-	/* Bottom bar.  May be 1 mixel taller than necessary due to rounding. */
-	vd->vd_driver->vd_drawrect(vd, 0, y - off_y, x, y, 1, c);
 
 	return (0);
 }
@@ -1283,11 +1364,6 @@ vt_change_font(struct vt_window *vw, str
 		VT_UNLOCK(vd);
 		return (EBUSY);
 	}
-	if (vd->vd_flags & VDF_TEXTMODE) {
-		/* Our device doesn't need fonts. */
-		VT_UNLOCK(vd);
-		return (ENOTTY);
-	}
 	vw->vw_flags |= VWF_BUSY;
 	VT_UNLOCK(vd);
 
@@ -1302,7 +1378,7 @@ vt_change_font(struct vt_window *vw, str
 
 	/* Actually apply the font to the current window. */
 	VT_LOCK(vd);
-	if (vw->vw_font != vf) {
+	if (vw->vw_font != vf && vw->vw_font != NULL && vf != NULL) {
 		/*
 		 * In case vt_change_font called to update size we don't need
 		 * to update font link.
@@ -1325,7 +1401,7 @@ vt_change_font(struct vt_window *vw, str
 
 	/* Force a full redraw the next timer tick. */
 	if (vd->vd_curwindow == vw) {
-		vt_set_border(vw, vf, TC_BLACK);
+		vt_set_border(vw, TC_BLACK);
 		vd->vd_flags |= VDF_INVALID;
 		vt_resume_flush_timer(vw->vw_device, 0);
 	}
@@ -2247,7 +2323,6 @@ vt_allocate(struct vt_driver *drv, void 
 		    main_vd->vd_driver->vd_name, drv->vd_name);
 	}
 	vd = main_vd;
-	VT_LOCK(vd);
 
 	if (vd->vd_flags & VDF_ASYNC) {
 		/* Stop vt_flush periodic task. */
@@ -2263,6 +2338,7 @@ vt_allocate(struct vt_driver *drv, void 
 	 * Reset VDF_TEXTMODE flag, driver who require that flag (vt_vga) will
 	 * set it.
 	 */
+	VT_LOCK(vd);
 	vd->vd_flags &= ~VDF_TEXTMODE;
 
 	vd->vd_driver = drv;

Modified: stable/10/sys/kern/kern_synch.c
==============================================================================
--- stable/10/sys/kern/kern_synch.c	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/kern/kern_synch.c	Thu Sep 18 14:38:18 2014	(r271769)
@@ -363,7 +363,7 @@ pause_sbt(const char *wmesg, sbintime_t 
 	if (sbt == 0)
 		sbt = tick_sbt;
 
-	if (cold) {
+	if (cold || kdb_active) {
 		/*
 		 * We delay one second at a time to avoid overflowing the
 		 * system specific DELAY() function(s):

Modified: stable/10/sys/kern/subr_terminal.c
==============================================================================
--- stable/10/sys/kern/subr_terminal.c	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/kern/subr_terminal.c	Thu Sep 18 14:38:18 2014	(r271769)
@@ -476,13 +476,17 @@ termcn_cnregister(struct terminal *tm)
 static void
 termcn_cngrab(struct consdev *cp)
 {
+	struct terminal *tm = cp->cn_arg;
 
+	tm->tm_class->tc_cngrab(tm);
 }
 
 static void
 termcn_cnungrab(struct consdev *cp)
 {
+	struct terminal *tm = cp->cn_arg;
 
+	tm->tm_class->tc_cnungrab(tm);
 }
 
 static void

Modified: stable/10/sys/powerpc/ps3/ps3_syscons.c
==============================================================================
--- stable/10/sys/powerpc/ps3/ps3_syscons.c	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/powerpc/ps3/ps3_syscons.c	Thu Sep 18 14:38:18 2014	(r271769)
@@ -78,6 +78,8 @@ static struct vt_driver vt_ps3fb_driver 
 	.vd_blank = vt_fb_blank,
 	.vd_bitblt_text = vt_fb_bitblt_text,
 	.vd_bitblt_bmp = vt_fb_bitblt_bitmap,
+	.vd_drawrect = vt_fb_drawrect,
+	.vd_setpixel = vt_fb_setpixel,
 	.vd_fb_ioctl = vt_fb_ioctl,
 	.vd_fb_mmap = vt_fb_mmap,
 	/* Better than VGA, but still generic driver. */

Modified: stable/10/sys/sys/terminal.h
==============================================================================
--- stable/10/sys/sys/terminal.h	Thu Sep 18 14:31:28 2014	(r271768)
+++ stable/10/sys/sys/terminal.h	Thu Sep 18 14:38:18 2014	(r271769)
@@ -155,6 +155,9 @@ typedef void tc_done_t(struct terminal *
 typedef void tc_cnprobe_t(struct terminal *tm, struct consdev *cd);
 typedef int tc_cngetc_t(struct terminal *tm);
 
+typedef void tc_cngrab_t(struct terminal *tm);
+typedef void tc_cnungrab_t(struct terminal *tm);
+
 typedef void tc_opened_t(struct terminal *tm, int opened);
 typedef int tc_ioctl_t(struct terminal *tm, u_long cmd, caddr_t data,
     struct thread *td);
@@ -175,6 +178,10 @@ struct terminal_class {
 	tc_cnprobe_t	*tc_cnprobe;
 	tc_cngetc_t	*tc_cngetc;
 
+	/* DDB & panic handling. */
+	tc_cngrab_t	*tc_cngrab;
+	tc_cnungrab_t	*tc_cnungrab;
+
 	/* Misc. */
 	tc_opened_t	*tc_opened;
 	tc_ioctl_t	*tc_ioctl;


More information about the svn-src-all mailing list