Index: sys/dev/drm2/drm_fb_helper.c =================================================================== --- sys/dev/drm2/drm_fb_helper.c +++ sys/dev/drm2/drm_fb_helper.c @@ -36,6 +36,8 @@ #include #include +#include + struct vt_kms_softc { struct drm_fb_helper *fb_helper; struct task fb_mode_task; @@ -64,7 +66,11 @@ 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); } Index: sys/dev/vt/vt.h =================================================================== --- sys/dev/vt/vt.h +++ sys/dev/vt/vt.h @@ -261,6 +261,8 @@ term_pos_t vw_offset; /* (?) Pixel offset. */ 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. */ Index: sys/dev/vt/vt_core.c =================================================================== --- sys/dev/vt/vt_core.c +++ sys/dev/vt/vt_core.c @@ -70,6 +70,9 @@ 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 @@ .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, @@ -191,6 +197,7 @@ .vw_device = &vt_consdev, .vw_terminal = &vt_consterm, .vw_kbdmode = K_XLATE, + .vw_grabbed = 0, }; static struct terminal vt_consterm = { .tm_class = &vt_termclass, @@ -1179,6 +1186,64 @@ } 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; Index: sys/kern/subr_terminal.c =================================================================== --- sys/kern/subr_terminal.c +++ sys/kern/subr_terminal.c @@ -476,13 +476,17 @@ 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 Index: sys/sys/terminal.h =================================================================== --- sys/sys/terminal.h +++ sys/sys/terminal.h @@ -155,6 +155,9 @@ 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 @@ 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;