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)
This commit is contained in:
parent
2bc2377c66
commit
4ed3581a36
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -61,6 +61,8 @@ static struct vt_driver vt_fb_early_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_priority = VD_PRIORITY_GENERIC,
|
||||
};
|
||||
|
||||
|
@ -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_ooffset_t offset, vm_paddr_t *paddr,
|
||||
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 x, int y, term_color_t color)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
vt_fb_drawrect(struct vt_device *vd, int x1, int y1, int x2, int y2, int fill,
|
||||
term_color_t color)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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 x1, int y1, int x2, int y2, int fill,
|
||||
{
|
||||
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++)
|
||||
|
@ -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. */
|
||||
|
@ -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_window *vw)
|
||||
struct vt_device *vd;
|
||||
struct vt_font *vf;
|
||||
|
||||
if (vw->vw_font == NULL)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
vf = vw->vw_font;
|
||||
|
||||
/*
|
||||
@ -1210,6 +1223,64 @@ vtterm_cngetc(struct terminal *tm)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -1228,30 +1299,40 @@ vtterm_opened(struct terminal *tm, int opened)
|
||||
}
|
||||
|
||||
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);
|
||||
/* 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_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 (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, struct vt_font *vf)
|
||||
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, struct vt_font *vf)
|
||||
|
||||
/* 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, struct vt_font *vf)
|
||||
|
||||
/* 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 *softc)
|
||||
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 *softc)
|
||||
* 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;
|
||||
|
@ -363,7 +363,7 @@ pause_sbt(const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags)
|
||||
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):
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -155,6 +155,9 @@ typedef void tc_done_t(struct terminal *tm);
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user