Index: sys/arm/conf/EFIKA_MX =================================================================== --- sys/arm/conf/EFIKA_MX (revision 264724) +++ sys/arm/conf/EFIKA_MX (working copy) @@ -171,7 +171,7 @@ # NOTE: serial console will be disabled if syscons enabled # Uncomment following lines for framebuffer/syscons support -device sc +device vt device kbdmux options SC_DFLT_FONT # compile font in makeoptions SC_DFLT_FONT=cp437 Index: sys/arm/freescale/imx/imx51_machdep.c =================================================================== --- sys/arm/freescale/imx/imx51_machdep.c (revision 264724) +++ sys/arm/freescale/imx/imx51_machdep.c (working copy) @@ -84,6 +84,7 @@ arm_devmap_add_entry(0x70000000, 0x00100000); arm_devmap_add_entry(0x73f00000, 0x00100000); arm_devmap_add_entry(0x83f00000, 0x00100000); + arm_devmap_add_entry(0xaef00000, 0x00400000); return (0); } Index: sys/boot/fdt/dts/arm/efikamx.dts =================================================================== --- sys/boot/fdt/dts/arm/efikamx.dts (revision 264724) +++ sys/boot/fdt/dts/arm/efikamx.dts (working copy) @@ -37,6 +37,7 @@ / { model = "Genesi Efika MX"; compatible = "genesi,imx51-efikamx"; + memreserve = <0xaef00000 0x00300000>; /* U-Boot's FB */ memory { /* RAM 512M */ @@ -43,11 +44,19 @@ reg = <0x90000000 0x20000000>; }; + localbus@5e000000 { - ipu3@5e000000 { - status = "okay"; - }; - }; + display: ipu3@5e000000 { + device_type = "display"; + /* Have to be filled by u-boot. */ + address = <0xaef76c60>; + depth = <24>; + width = <1280>; + height = <720>; + linebytes = <3840>; + status = "okay"; + }; + }; soc@70000000 { aips@70000000 { @@ -118,6 +127,7 @@ aliases { UART1 = &UART1; SSI2 = &SSI2; + screen = &display; }; chosen { Index: sys/dev/vt/hw/efifb/efifb.c =================================================================== --- sys/dev/vt/hw/efifb/efifb.c (revision 264724) +++ sys/dev/vt/hw/efifb/efifb.c (working copy) @@ -51,36 +51,58 @@ #include #include -static vd_init_t vt_efb_init; +static vd_init_t vt_efifb_init; +static vd_probe_t vt_efifb_probe; -static struct vt_driver vt_efb_driver = { - .vd_init = vt_efb_init, +static struct vt_driver vt_efifb_driver = { + .vd_name = "efifb", + .vd_probe = vt_efifb_probe, + .vd_init = vt_efifb_init, .vd_blank = vt_fb_blank, .vd_bitbltchr = vt_fb_bitbltchr, + .vd_maskbitbltchr = vt_fb_maskbitbltchr, /* Better than VGA, but still generic driver. */ .vd_priority = VD_PRIORITY_GENERIC + 1, }; -static struct fb_info info; -VT_CONSDEV_DECLARE(vt_efb_driver, - MAX(80, PIXEL_WIDTH(VT_FB_DEFAULT_WIDTH)), - MAX(25, PIXEL_HEIGHT(VT_FB_DEFAULT_HEIGHT)), &info); +static struct fb_info local_info; +VT_DRIVER_DECLARE(vt_efifb, vt_efifb_driver); static int -vt_efb_init(struct vt_device *vd) +vt_efifb_probe(struct vt_device *vd) { - int depth, d, disable, i, len; + int disabled; + struct efi_fb *efifb; + caddr_t kmdp; + + disabled = 0; + TUNABLE_INT_FETCH("hw.syscons.disable", &disabled); + if (disabled != 0) + return (CN_DEAD); + + kmdp = preload_search_by_type("elf kernel"); + if (kmdp == NULL) + kmdp = preload_search_by_type("elf64 kernel"); + efifb = (struct efi_fb *)preload_search_info(kmdp, + MODINFO_METADATA | MODINFOMD_EFI_FB); + if (efifb == NULL) + return (CN_DEAD); + + return (CN_INTERNAL); +} + +static int +vt_efifb_init(struct vt_device *vd) +{ + int depth, d, i, len; struct fb_info *info; struct efi_fb *efifb; caddr_t kmdp; info = vd->vd_softc; + if (info == NULL) + info = vd->vd_softc = (void *)&local_info; - disable = 0; - TUNABLE_INT_FETCH("hw.syscons.disable", &disable); - if (disable != 0) - return (CN_DEAD); - kmdp = preload_search_by_type("elf kernel"); if (kmdp == NULL) kmdp = preload_search_by_type("elf64 kernel"); @@ -136,7 +158,8 @@ fb_probe(info); vt_fb_init(vd); + /* Clear the screen. */ + vt_fb_blank(vd, TC_BLACK); return (CN_INTERNAL); } - Index: sys/dev/vt/hw/fb/vt_early_fb.c =================================================================== --- sys/dev/vt/hw/fb/vt_early_fb.c (revision 264724) +++ sys/dev/vt/hw/fb/vt_early_fb.c (working copy) @@ -52,8 +52,11 @@ #include static vd_init_t vt_efb_init; +static vd_probe_t vt_efb_probe; static struct vt_driver vt_fb_early_driver = { + .vd_name = "efb", + .vd_probe = vt_efb_probe, .vd_init = vt_efb_init, .vd_blank = vt_fb_blank, .vd_bitbltchr = vt_fb_bitbltchr, @@ -60,10 +63,8 @@ .vd_priority = VD_PRIORITY_GENERIC, }; -static struct fb_info info; -VT_CONSDEV_DECLARE(vt_fb_early_driver, - MAX(80, PIXEL_WIDTH(VT_FB_DEFAULT_WIDTH)), - MAX(25, PIXEL_HEIGHT(VT_FB_DEFAULT_HEIGHT)), &info); +static struct fb_info local_info; +VT_DRIVER_DECLARE(vt_efb, vt_fb_early_driver); static void #ifdef FDT @@ -126,32 +127,64 @@ } } -static int -vt_efb_init(struct vt_device *vd) +static phandle_t +vt_efb_get_fbnode() { - struct ofw_pci_register pciaddrs[8]; - struct fb_info *info; - int i, len, n_pciaddrs; phandle_t chosen, node; ihandle_t stdout; char type[64]; - info = vd->vd_softc; - chosen = OF_finddevice("/chosen"); OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); node = OF_instance_to_package(stdout); - if (node == -1) { - /* - * The "/chosen/stdout" does not exist try - * using "screen" directly. - */ - node = OF_finddevice("screen"); + if (node != -1) { + /* The "/chosen/stdout" present. */ + OF_getprop(node, "device_type", type, sizeof(type)); + /* Check if it has "display" type. */ + if (strcmp(type, "display") == 0) + return (node); } - OF_getprop(node, "device_type", type, sizeof(type)); - if (strcmp(type, "display") != 0) + /* Try device with name "screen". */ + node = OF_finddevice("screen"); + + return (node); +} + +static int +vt_efb_probe(struct vt_device *vd) +{ + phandle_t node; + + node = vt_efb_get_fbnode(); + if (node == -1) return (CN_DEAD); + if ((OF_getproplen(node, "height") <= 0) || + (OF_getproplen(node, "width") <= 0) || + (OF_getproplen(node, "depth") <= 0) || + (OF_getproplen(node, "linebytes") <= 0)) + return (CN_DEAD); + + return (CN_INTERNAL); +} + +static int +vt_efb_init(struct vt_device *vd) +{ + struct ofw_pci_register pciaddrs[8]; + struct fb_info *info; + int i, len, n_pciaddrs; + phandle_t node; + + if (vd->vd_softc == NULL) + vd->vd_softc = (void *)&local_info; + + info = vd->vd_softc; + + node = vt_efb_get_fbnode(); + if (node == -1) + return (CN_DEAD); + #define GET(name, var) \ if (OF_getproplen(node, (name)) != sizeof(info->fb_##var)) \ return (CN_DEAD); \ @@ -249,7 +282,6 @@ #endif } - /* blank full size */ len = info->fb_size / 4; for (i = 0; i < len; i++) { @@ -274,6 +306,5 @@ fb_probe(info); vt_fb_init(vd); - return (CN_INTERNAL); } Index: sys/dev/vt/hw/fb/vt_fb.c =================================================================== --- sys/dev/vt/hw/fb/vt_fb.c (revision 264724) +++ sys/dev/vt/hw/fb/vt_fb.c (working copy) @@ -50,9 +50,11 @@ void vt_fb_setpixel(struct vt_device *vd, int x, int y, term_color_t color); static struct vt_driver vt_fb_driver = { + .vd_name = "fb", .vd_init = vt_fb_init, .vd_blank = vt_fb_blank, .vd_bitbltchr = vt_fb_bitbltchr, + .vd_maskbitbltchr = vt_fb_maskbitbltchr, .vd_drawrect = vt_fb_drawrect, .vd_setpixel = vt_fb_setpixel, .vd_postswitch = vt_fb_postswitch, @@ -61,6 +63,8 @@ .vd_fb_mmap = vt_fb_mmap, }; +VT_DRIVER_DECLARE(vt_fb, vt_fb_driver); + static int vt_fb_ioctl(struct vt_device *vd, u_long cmd, caddr_t data, struct thread *td) { @@ -189,6 +193,68 @@ uint32_t fgc, bgc, cc, o; int c, l, bpp; u_long line; + uint8_t b; + const uint8_t *ch; + + info = vd->vd_softc; + bpp = FBTYPE_GET_BYTESPP(info); + fgc = info->fb_cmap[fg]; + bgc = info->fb_cmap[bg]; + b = 0; + if (bpl == 0) + bpl = (width + 7) >> 3; /* Bytes per sorce line. */ + + /* Don't try to put off screen pixels */ + if (((left + width) > info->fb_width) || ((top + height) > + info->fb_height)) + return; + + line = (info->fb_stride * top) + (left * bpp); + for (l = 0; l < height; l++) { + ch = src; + for (c = 0; c < width; c++) { + if (c % 8 == 0) + b = *ch++; + else + b <<= 1; + o = line + (c * bpp); + cc = b & 0x80 ? fgc : bgc; + + switch(bpp) { + case 1: + info->wr1(info, o, cc); + break; + case 2: + info->wr2(info, o, cc); + break; + case 3: + /* Packed mode, so unaligned. Byte access. */ + info->wr1(info, o, (cc >> 16) & 0xff); + info->wr1(info, o + 1, (cc >> 8) & 0xff); + info->wr1(info, o + 2, cc & 0xff); + break; + case 4: + info->wr4(info, o, cc); + break; + default: + /* panic? */ + break; + } + } + line += info->fb_stride; + src += bpl; + } +} + +void +vt_fb_maskbitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask, + int bpl, vt_axis_t top, vt_axis_t left, unsigned int width, + unsigned int height, term_color_t fg, term_color_t bg) +{ + struct fb_info *info; + uint32_t fgc, bgc, cc, o; + int c, l, bpp; + u_long line; uint8_t b, m; const uint8_t *ch; Index: sys/dev/vt/hw/fb/vt_fb.h =================================================================== --- sys/dev/vt/hw/fb/vt_fb.h (revision 264724) +++ sys/dev/vt/hw/fb/vt_fb.h (working copy) @@ -41,7 +41,7 @@ vd_init_t vt_fb_init; vd_blank_t vt_fb_blank; vd_bitbltchr_t vt_fb_bitbltchr; +vd_maskbitbltchr_t vt_fb_maskbitbltchr; vd_postswitch_t vt_fb_postswitch; - #endif /* _DEV_VT_HW_FB_VT_FB_H_ */ Index: sys/dev/vt/hw/ofwfb/ofwfb.c =================================================================== --- sys/dev/vt/hw/ofwfb/ofwfb.c (revision 264724) +++ sys/dev/vt/hw/ofwfb/ofwfb.c (working copy) @@ -63,6 +63,7 @@ static vd_bitbltchr_t ofwfb_bitbltchr; static const struct vt_driver vt_ofwfb_driver = { + .vd_name = "ofwfb", .vd_init = ofwfb_init, .vd_blank = ofwfb_blank, .vd_bitbltchr = ofwfb_bitbltchr, Index: sys/dev/vt/hw/vga/vga.c =================================================================== --- sys/dev/vt/hw/vga/vga.c (revision 264724) +++ sys/dev/vt/hw/vga/vga.c (working copy) @@ -71,6 +71,7 @@ #define VT_VGA_HEIGHT 480 #define VT_VGA_MEMSIZE (VT_VGA_WIDTH * VT_VGA_HEIGHT / 8) +static vd_probe_t vga_probe; static vd_init_t vga_init; static vd_blank_t vga_blank; static vd_bitbltchr_t vga_bitbltchr; @@ -81,6 +82,8 @@ static vd_postswitch_t vga_postswitch; static const struct vt_driver vt_vga_driver = { + .vd_name = "vga", + .vd_probe = vga_probe, .vd_init = vga_init, .vd_blank = vga_blank, .vd_bitbltchr = vga_bitbltchr, @@ -97,8 +100,7 @@ * buffer is always big enough to support both. */ static struct vga_softc vga_conssoftc; -VT_CONSDEV_DECLARE(vt_vga_driver, MAX(80, PIXEL_WIDTH(VT_VGA_WIDTH)), - MAX(25, PIXEL_HEIGHT(VT_VGA_HEIGHT)), &vga_conssoftc); +VT_DRIVER_DECLARE(vt_vga, vt_vga_driver); static inline void vga_setcolor(struct vt_device *vd, term_color_t color) @@ -631,11 +633,23 @@ } static int +vga_probe(struct vt_device *vd) +{ + + return (CN_INTERNAL); +} + +static int vga_init(struct vt_device *vd) { - struct vga_softc *sc = vd->vd_softc; - int textmode = 0; + struct vga_softc *sc; + int textmode; + if (vd->vd_softc == NULL) + vd->vd_softc = (void *)&vga_conssoftc; + sc = vd->vd_softc; + textmode = 0; + #if defined(__amd64__) || defined(__i386__) sc->vga_fb_tag = X86_BUS_SPACE_MEM; sc->vga_fb_handle = KERNBASE + VGA_MEM_BASE; Index: sys/dev/vt/hw/xboxfb/xboxfb.c =================================================================== --- sys/dev/vt/hw/xboxfb/xboxfb.c (revision 264724) +++ sys/dev/vt/hw/xboxfb/xboxfb.c (working copy) @@ -57,6 +57,7 @@ static vd_init_t xboxfb_init; static struct vt_driver xboxfb_driver = { + .vd_name = "xboxfb", .vd_init = xboxfb_init, .vd_blank = vt_fb_blank, .vd_bitbltchr = vt_fb_bitbltchr, Index: sys/dev/vt/vt.h =================================================================== --- sys/dev/vt/vt.h (revision 264724) +++ sys/dev/vt/vt.h (working copy) @@ -277,6 +277,7 @@ */ typedef int vd_init_t(struct vt_device *vd); +typedef int vd_probe_t(struct vt_device *vd); typedef void vd_postswitch_t(struct vt_device *vd); typedef void vd_blank_t(struct vt_device *vd, term_color_t color); typedef void vd_bitbltchr_t(struct vt_device *vd, const uint8_t *src, @@ -295,7 +296,9 @@ typedef void vd_setpixel_t(struct vt_device *, int, int, term_color_t); struct vt_driver { + char vd_name[16]; /* Console attachment. */ + vd_probe_t *vd_probe; vd_init_t *vd_init; /* Drawing. */ @@ -391,6 +394,9 @@ SYSINIT(vt_early_cons, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_ANY, \ vt_upgrade, &driver ## _consdev) +/* name argument is not used yet. */ +#define VT_DRIVER_DECLARE(name, drv) DATA_SET(vt_drv_set, drv) + /* * Fonts. * Index: sys/dev/vt/vt_consolectl.c =================================================================== --- sys/dev/vt/vt_consolectl.c (revision 264724) +++ sys/dev/vt/vt_consolectl.c (working copy) @@ -51,7 +51,7 @@ { switch (cmd) { - case CONS_GETVERS: + case CONS_GETVERS: *(int*)data = 0x200; return 0; case CONS_MOUSECTL: { @@ -61,7 +61,7 @@ return (0); } default: - printf("consolectl: unknown ioctl: %c:%lx\n", + DPRINTF(1, "consolectl: unknown ioctl: %c:%lx\n", (char)IOCGROUP(cmd), IOCBASECMD(cmd)); return (ENOIOCTL); } Index: sys/dev/vt/vt_core.c =================================================================== --- sys/dev/vt/vt_core.c (revision 264724) +++ sys/dev/vt/vt_core.c (working copy) @@ -144,8 +144,85 @@ static int vt_late_window_switch(struct vt_window *); static int vt_proc_alive(struct vt_window *); static void vt_resize(struct vt_device *); +static void vt_update_static(void *); +SET_DECLARE(vt_drv_set, struct vt_driver); + +#define _VTDEFH MAX(100, PIXEL_HEIGHT(VT_FB_DEFAULT_HEIGHT)) +#define _VTDEFW MAX(200, PIXEL_WIDTH(VT_FB_DEFAULT_WIDTH)) + +static struct terminal vt_consterm; +static struct vt_window vt_conswindow; +static struct vt_device vt_consdev = { + .vd_driver = NULL, + .vd_softc = NULL, + .vd_flags = VDF_INVALID, + .vd_windows = { [VT_CONSWINDOW] = &vt_conswindow, }, + .vd_curwindow = &vt_conswindow, + .vd_markedwin = NULL, + .vd_kbstate = 0, +}; +static term_char_t vt_constextbuf[(_VTDEFW) * (VBF_DEFAULT_HISTORY_SIZE)]; +static term_char_t *vt_constextbufrows[VBF_DEFAULT_HISTORY_SIZE]; +static struct vt_window vt_conswindow = { + .vw_number = VT_CONSWINDOW, + .vw_flags = VWF_CONSOLE, + .vw_buf = { + .vb_buffer = vt_constextbuf, + .vb_rows = vt_constextbufrows, + .vb_history_size = VBF_DEFAULT_HISTORY_SIZE, + .vb_curroffset = 0, + .vb_roffset = 0, + .vb_flags = VBF_STATIC, + .vb_mark_start = {.tp_row = 0, .tp_col = 0,}, + .vb_mark_end = {.tp_row = 0, .tp_col = 0,}, + .vb_scr_size = { + .tp_row = _VTDEFH, + .tp_col = _VTDEFW, + }, + }, + .vw_device = &vt_consdev, + .vw_terminal = &vt_consterm, + .vw_kbdmode = K_XLATE, +}; +static struct terminal vt_consterm = { + .tm_class = &vt_termclass, + .tm_softc = &vt_conswindow, + .tm_flags = TF_CONS, +}; +static struct consdev vt_consterm_consdev = { + .cn_ops = &termcn_cnops, + .cn_arg = &vt_consterm, + .cn_name = "ttyv0", +}; + +/* Add to set of consoles. */ +DATA_SET(cons_set, vt_consterm_consdev); + +/* + * Right after kmem is done to allow early drivers to use locking and allocate + * memory. + */ +SYSINIT(vt_update_static, SI_SUB_KMEM, SI_ORDER_ANY, vt_update_static, + &vt_consdev); +/* Delay until all devices attached, to not waste time. */ +SYSINIT(vt_early_cons, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_ANY, vt_upgrade, + &vt_consdev); + +/* Initialize locks/mem depended members. */ static void +vt_update_static(void *dummy) +{ + + if (main_vd != 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"); + } +} + +static void vt_switch_timer(void *arg) { @@ -775,7 +852,7 @@ if ((vd->vd_flags & (VDF_MOUSECURSOR|VDF_TEXTMODE)) == VDF_MOUSECURSOR) { m = &vt_default_mouse_pointer; - bpl = (m->w + 7) >> 3; /* Bytes per sorce line. */ + bpl = (m->w + 7) >> 3; /* Bytes per source line. */ w = m->w; h = m->h; @@ -851,9 +928,11 @@ } #endif + static void vtterm_cnprobe(struct terminal *tm, struct consdev *cp) { + struct vt_driver *vtd, **vtdlist, *vtdbest = NULL; struct vt_window *vw = tm->tm_softc; struct vt_device *vd = vw->vw_device; struct winsize wsz; @@ -862,6 +941,24 @@ /* Initialization already done. */ return; + SET_FOREACH(vtdlist, vt_drv_set) { + vtd = *vtdlist; + if (vtd->vd_probe == NULL) + continue; + if (vtd->vd_probe(vd) == CN_DEAD) + continue; + if ((vtdbest == NULL) || + (vtd->vd_priority > vtdbest->vd_priority)) + vtdbest = vtd; + } + if (vtdbest == NULL) { + cp->cn_pri = CN_DEAD; + vd->vd_flags |= VDF_DEAD; + return; + } + + vd->vd_driver = vtdbest; + cp->cn_pri = vd->vd_driver->vd_init(vd); if (cp->cn_pri == CN_DEAD) { vd->vd_flags |= VDF_DEAD; @@ -1705,6 +1802,7 @@ vw->vw_flags |= VWF_VTYLOCK; else vw->vw_flags &= ~VWF_VTYLOCK; + return (0); case VT_OPENQRY: VT_LOCK(vd); for (i = 0; i < VT_MAXWINDOWS; i++) { @@ -1871,12 +1969,6 @@ return; vd->vd_flags |= VDF_ASYNC; - mtx_init(&vd->vd_lock, "vtdev", NULL, MTX_DEF); - cv_init(&vd->vd_winswitch, "vtwswt"); - - /* Init 25 Hz timer. */ - callout_init_mtx(&vd->vd_timer, &vd->vd_lock, 0); - for (i = 0; i < VT_MAXWINDOWS; i++) { vw = vd->vd_windows[i]; if (vw == NULL) { @@ -1894,6 +1986,7 @@ 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]; @@ -1901,8 +1994,12 @@ 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); + /* Start timer when everything ready. */ callout_reset(&vd->vd_timer, hz / VT_TIMERFREQ, vt_timer, vd); + VT_UNLOCK(vd); } static void @@ -1913,9 +2010,11 @@ for (i = 0; i < VT_MAXWINDOWS; i++) { vw = vd->vd_windows[i]; + VT_LOCK(vd); /* Assign default font to window, if not textmode. */ if (!(vd->vd_flags & VDF_TEXTMODE) && vw->vw_font == NULL) vw->vw_font = vtfont_ref(&vt_font_default); + VT_UNLOCK(vd); /* Resize terminal windows */ vt_change_font(vw, vw->vw_font); } @@ -1929,7 +2028,11 @@ if (main_vd == NULL) { main_vd = malloc(sizeof *vd, M_VT, M_WAITOK|M_ZERO); - printf("%s: VT initialize with new VT driver.\n", __func__); + 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: @@ -1936,14 +2039,15 @@ * it is bad idea to replace KMS driver with generic VGA one. */ if (drv->vd_priority <= main_vd->vd_driver->vd_priority) { - printf("%s: Driver priority %d too low. Current %d\n ", - __func__, drv->vd_priority, - main_vd->vd_driver->vd_priority); + printf("VT: Driver priority %d too low. Current %d\n ", + drv->vd_priority, main_vd->vd_driver->vd_priority); return; } - printf("%s: Replace existing VT driver.\n", __func__); + printf("VT: Replacing driver \"%s\" with new \"%s\".\n", + main_vd->vd_driver->vd_name, drv->vd_name); } vd = main_vd; + VT_LOCK(vd); if (drv->vd_maskbitbltchr == NULL) drv->vd_maskbitbltchr = drv->vd_bitbltchr; @@ -1966,6 +2070,7 @@ vd->vd_driver = drv; vd->vd_softc = softc; vd->vd_driver->vd_init(vd); + VT_UNLOCK(vd); vt_upgrade(vd); Index: sys/dev/vt/vt_sysmouse.c =================================================================== --- sys/dev/vt/vt_sysmouse.c (revision 264724) +++ sys/dev/vt/vt_sysmouse.c (working copy) @@ -376,7 +376,7 @@ case MOUSE_MOUSECHAR: return (0); default: - printf("sysmouse: unknown ioctl: %c:%lx\n", + DPRINTF(1, "sysmouse: unknown ioctl: %c:%lx\n", (char)IOCGROUP(cmd), IOCBASECMD(cmd)); return (ENOIOCTL); }