]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/syscons/syscons.c
Update ELF Tool Chain to upstream r3769
[FreeBSD/FreeBSD.git] / sys / dev / syscons / syscons.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1992-1998 Søren Schmidt
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The DragonFly Project
8  * by Sascha Wildner <saw@online.de>
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer,
15  *    without modification, immediately at the beginning of the file.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include "opt_syscons.h"
38 #include "opt_splash.h"
39 #include "opt_ddb.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/bus.h>
44 #include <sys/conf.h>
45 #include <sys/cons.h>
46 #include <sys/consio.h>
47 #include <sys/kdb.h>
48 #include <sys/eventhandler.h>
49 #include <sys/fbio.h>
50 #include <sys/kbio.h>
51 #include <sys/kernel.h>
52 #include <sys/lock.h>
53 #include <sys/malloc.h>
54 #include <sys/mutex.h>
55 #include <sys/pcpu.h>
56 #include <sys/priv.h>
57 #include <sys/proc.h>
58 #include <sys/random.h>
59 #include <sys/reboot.h>
60 #include <sys/serial.h>
61 #include <sys/signalvar.h>
62 #include <sys/smp.h>
63 #include <sys/sysctl.h>
64 #include <sys/tty.h>
65 #include <sys/power.h>
66
67 #include <machine/clock.h>
68 #if defined(__arm__) || defined(__mips__) || defined(__powerpc__) || \
69     defined(__sparc64__)
70 #include <machine/sc_machdep.h>
71 #else
72 #include <machine/pc/display.h>
73 #endif
74 #if defined(__i386__) || defined(__amd64__)
75 #include <machine/psl.h>
76 #include <machine/frame.h>
77 #endif
78 #include <machine/stdarg.h>
79
80 #if defined(__amd64__) || defined(__i386__)
81 #include <machine/vmparam.h>
82
83 #include <vm/vm.h>
84 #include <vm/pmap.h>
85 #endif
86
87 #include <dev/kbd/kbdreg.h>
88 #include <dev/fb/fbreg.h>
89 #include <dev/fb/splashreg.h>
90 #include <dev/syscons/syscons.h>
91
92 #define COLD 0
93 #define WARM 1
94
95 #define DEFAULT_BLANKTIME (5 * 60) /* 5 minutes */
96 #define MAX_BLANKTIME (7 * 24 * 60 * 60) /* 7 days!? */
97
98 #define KEYCODE_BS 0x0e /* "<-- Backspace" key, XXX */
99
100 /* NULL-safe version of "tty_opened()" */
101 #define tty_opened_ns(tp) ((tp) != NULL && tty_opened(tp))
102
103 static u_char sc_kattrtab[MAXCPU];
104
105 static int sc_console_unit = -1;
106 static int sc_saver_keyb_only = 1;
107 static scr_stat *sc_console;
108 static struct consdev *sc_consptr;
109 static void *sc_kts[MAXCPU];
110 static struct sc_term_sw *sc_ktsw;
111 static scr_stat main_console;
112 static struct tty *main_devs[MAXCONS];
113
114 static char init_done = COLD;
115 static int shutdown_in_progress = FALSE;
116 static int suspend_in_progress = FALSE;
117 static char sc_malloc = FALSE;
118
119 static int saver_mode = CONS_NO_SAVER; /* LKM/user saver */
120 static int run_scrn_saver = FALSE; /* should run the saver? */
121 static int enable_bell = TRUE; /* enable beeper */
122
123 #ifndef SC_DISABLE_REBOOT
124 static int enable_reboot = TRUE; /* enable keyboard reboot */
125 #endif
126
127 #ifndef SC_DISABLE_KDBKEY
128 static int enable_kdbkey = TRUE; /* enable keyboard debug */
129 #endif
130
131 static long scrn_blank_time = 0; /* screen saver timeout value */
132 #ifdef DEV_SPLASH
133 static int scrn_blanked; /* # of blanked screen */
134 static int sticky_splash = FALSE;
135
136 static void
137 none_saver(sc_softc_t *sc, int blank)
138 {
139 }
140 static void (*current_saver)(sc_softc_t *, int) = none_saver;
141 #endif
142
143 #ifdef SC_NO_SUSPEND_VTYSWITCH
144 static int sc_no_suspend_vtswitch = 1;
145 #else
146 static int sc_no_suspend_vtswitch = 0;
147 #endif
148 static int sc_susp_scr;
149
150 static SYSCTL_NODE(_hw, OID_AUTO, syscons, CTLFLAG_RD, 0, "syscons");
151 static SYSCTL_NODE(_hw_syscons, OID_AUTO, saver, CTLFLAG_RD, 0, "saver");
152 SYSCTL_INT(_hw_syscons_saver, OID_AUTO, keybonly, CTLFLAG_RW,
153     &sc_saver_keyb_only, 0, "screen saver interrupted by input only");
154 SYSCTL_INT(
155     _hw_syscons, OID_AUTO, bell, CTLFLAG_RW, &enable_bell, 0, "enable bell");
156 #ifndef SC_DISABLE_REBOOT
157 SYSCTL_INT(_hw_syscons, OID_AUTO, kbd_reboot, CTLFLAG_RW | CTLFLAG_SECURE,
158     &enable_reboot, 0, "enable keyboard reboot");
159 #endif
160 #ifndef SC_DISABLE_KDBKEY
161 SYSCTL_INT(_hw_syscons, OID_AUTO, kbd_debug, CTLFLAG_RW | CTLFLAG_SECURE,
162     &enable_kdbkey, 0, "enable keyboard debug");
163 #endif
164 SYSCTL_INT(_hw_syscons, OID_AUTO, sc_no_suspend_vtswitch, CTLFLAG_RWTUN,
165     &sc_no_suspend_vtswitch, 0, "Disable VT switch before suspend.");
166 #if !defined(SC_NO_FONT_LOADING) && defined(SC_DFLT_FONT)
167 #include "font.h"
168 #endif
169
170 tsw_ioctl_t *sc_user_ioctl;
171
172 static bios_values_t bios_value;
173
174 static int enable_panic_key;
175 SYSCTL_INT(_machdep, OID_AUTO, enable_panic_key, CTLFLAG_RW, &enable_panic_key,
176     0, "Enable panic via keypress specified in kbdmap(5)");
177
178 #define SC_CONSOLECTL 255
179
180 #define VTY_WCHAN(sc, vty) (&SC_DEV(sc, vty))
181
182 /* prototypes */
183 static int sc_allocate_keyboard(sc_softc_t *sc, int unit);
184 static int scvidprobe(int unit, int flags, int cons);
185 static int sckbdprobe(int unit, int flags, int cons);
186 static void scmeminit(void *arg);
187 static int scdevtounit(struct tty *tp);
188 static kbd_callback_func_t sckbdevent;
189 static void scinit(int unit, int flags);
190 static scr_stat *sc_get_stat(struct tty *tp);
191 static void scterm(int unit, int flags);
192 static void scshutdown(void *, int);
193 static void scsuspend(void *);
194 static void scresume(void *);
195 static u_int scgetc(sc_softc_t *sc, u_int flags, struct sc_cnstate *sp);
196 static void sc_puts(scr_stat *scp, u_char *buf, int len);
197 #define SCGETC_CN 1
198 #define SCGETC_NONBLOCK 2
199 static void sccnupdate(scr_stat *scp);
200 static scr_stat *alloc_scp(sc_softc_t *sc, int vty);
201 static void init_scp(sc_softc_t *sc, int vty, scr_stat *scp);
202 static timeout_t scrn_timer;
203 static int and_region(int *s1, int *e1, int s2, int e2);
204 static void scrn_update(scr_stat *scp, int show_cursor);
205
206 #ifdef DEV_SPLASH
207 static int scsplash_callback(int event, void *arg);
208 static void scsplash_saver(sc_softc_t *sc, int show);
209 static int add_scrn_saver(void (*this_saver)(sc_softc_t *, int));
210 static int remove_scrn_saver(void (*this_saver)(sc_softc_t *, int));
211 static int set_scrn_saver_mode(
212     scr_stat *scp, int mode, u_char *pal, int border);
213 static int restore_scrn_saver_mode(scr_stat *scp, int changemode);
214 static void stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int));
215 static int wait_scrn_saver_stop(sc_softc_t *sc);
216 #define scsplash_stick(stick) (sticky_splash = (stick))
217 #else /* !DEV_SPLASH */
218 #define scsplash_stick(stick)
219 #endif /* DEV_SPLASH */
220
221 static int do_switch_scr(sc_softc_t *sc, int s);
222 static int vt_proc_alive(scr_stat *scp);
223 static int signal_vt_rel(scr_stat *scp);
224 static int signal_vt_acq(scr_stat *scp);
225 static int finish_vt_rel(scr_stat *scp, int release, int *s);
226 static int finish_vt_acq(scr_stat *scp);
227 static void exchange_scr(sc_softc_t *sc);
228 static void update_cursor_image(scr_stat *scp);
229 static void change_cursor_shape(scr_stat *scp, int flags, int base, int height);
230 static void update_font(scr_stat *);
231 static int save_kbd_state(scr_stat *scp);
232 static int update_kbd_state(scr_stat *scp, int state, int mask);
233 static int update_kbd_leds(scr_stat *scp, int which);
234 static int sc_kattr(void);
235 static timeout_t blink_screen;
236 static struct tty *sc_alloc_tty(int, int);
237
238 static cn_probe_t sc_cnprobe;
239 static cn_init_t sc_cninit;
240 static cn_term_t sc_cnterm;
241 static cn_getc_t sc_cngetc;
242 static cn_putc_t sc_cnputc;
243 static cn_grab_t sc_cngrab;
244 static cn_ungrab_t sc_cnungrab;
245
246 CONSOLE_DRIVER(sc);
247
248 static tsw_open_t sctty_open;
249 static tsw_close_t sctty_close;
250 static tsw_outwakeup_t sctty_outwakeup;
251 static tsw_ioctl_t sctty_ioctl;
252 static tsw_mmap_t sctty_mmap;
253
254 static struct ttydevsw sc_ttydevsw = {
255         .tsw_open = sctty_open,
256         .tsw_close = sctty_close,
257         .tsw_outwakeup = sctty_outwakeup,
258         .tsw_ioctl = sctty_ioctl,
259         .tsw_mmap = sctty_mmap,
260 };
261
262 static d_ioctl_t consolectl_ioctl;
263 static d_close_t consolectl_close;
264
265 static struct cdevsw consolectl_devsw = {
266         .d_version = D_VERSION,
267         .d_flags = D_NEEDGIANT | D_TRACKCLOSE,
268         .d_ioctl = consolectl_ioctl,
269         .d_close = consolectl_close,
270         .d_name = "consolectl",
271 };
272
273 /* ec -- emergency console. */
274
275 static u_int ec_scroffset;
276
277 static void
278 ec_putc(int c)
279 {
280         uintptr_t fb;
281         u_short *scrptr;
282         u_int ind;
283         int attr, column, mysize, width, xsize, yborder, ysize;
284
285         if (c < 0 || c > 0xff || c == '\a')
286                 return;
287         if (sc_console == NULL) {
288 #if !defined(__amd64__) && !defined(__i386__)
289                 return;
290 #else
291                 /*
292                  * This is enough for ec_putc() to work very early on x86
293                  * if the kernel starts in normal color text mode.
294                  */
295 #ifdef __amd64__
296                 fb = KERNBASE + 0xb8000;
297 #else /* __i386__ */
298                 fb = pmap_get_map_low() + 0xb8000;
299 #endif
300                 xsize = 80;
301                 ysize = 25;
302 #endif
303         } else {
304                 if (!ISTEXTSC(&main_console))
305                         return;
306                 fb = main_console.sc->adp->va_window;
307                 xsize = main_console.xsize;
308                 ysize = main_console.ysize;
309         }
310         yborder = ysize / 5;
311         scrptr = (u_short *)(void *)fb + xsize * yborder;
312         mysize = xsize * (ysize - 2 * yborder);
313         do {
314                 ind = ec_scroffset;
315                 column = ind % xsize;
316                 width = (c == '\b' ?
317                         -1 :
318                         c == '\t' ?
319                         (column + 8) & ~7 :
320                         c == '\r' ? -column : c == '\n' ? xsize - column : 1);
321                 if (width == 0 || (width < 0 && ind < -width))
322                         return;
323         } while (atomic_cmpset_rel_int(&ec_scroffset, ind, ind + width) == 0);
324         if (c == '\b' || c == '\r')
325                 return;
326         if (c == '\n')
327                 ind += xsize; /* XXX clearing from new pos is not atomic */
328
329         attr = sc_kattr();
330         if (c == '\t' || c == '\n')
331                 c = ' ';
332         do
333                 scrptr[ind++ % mysize] = (attr << 8) | c;
334         while (--width != 0);
335 }
336
337 int
338 sc_probe_unit(int unit, int flags)
339 {
340         if (!vty_enabled(VTY_SC))
341                 return ENXIO;
342         if (!scvidprobe(unit, flags, FALSE)) {
343                 if (bootverbose)
344                         printf("%s%d: no video adapter found.\n",
345                             SC_DRIVER_NAME, unit);
346                 return ENXIO;
347         }
348
349         /* syscons will be attached even when there is no keyboard */
350         sckbdprobe(unit, flags, FALSE);
351
352         return 0;
353 }
354
355 /* probe video adapters, return TRUE if found */
356 static int
357 scvidprobe(int unit, int flags, int cons)
358 {
359         /*
360          * Access the video adapter driver through the back door!
361          * Video adapter drivers need to be configured before syscons.
362          * However, when syscons is being probed as the low-level console,
363          * they have not been initialized yet.  We force them to initialize
364          * themselves here. XXX
365          */
366         vid_configure(cons ? VIO_PROBE_ONLY : 0);
367
368         return (vid_find_adapter("*", unit) >= 0);
369 }
370
371 /* probe the keyboard, return TRUE if found */
372 static int
373 sckbdprobe(int unit, int flags, int cons)
374 {
375         /* access the keyboard driver through the backdoor! */
376         kbd_configure(cons ? KB_CONF_PROBE_ONLY : 0);
377
378         return (kbd_find_keyboard("*", unit) >= 0);
379 }
380
381 static char *
382 adapter_name(video_adapter_t *adp)
383 {
384         static struct {
385                 int type;
386                 char *name[2];
387         } names[] = {
388                 { KD_MONO, { "MDA", "MDA" } },
389                 { KD_HERCULES, { "Hercules", "Hercules" } },
390                 { KD_CGA, { "CGA", "CGA" } },
391                 { KD_EGA, { "EGA", "EGA (mono)" } },
392                 { KD_VGA, { "VGA", "VGA (mono)" } },
393                 { KD_TGA, { "TGA", "TGA" } },
394                 { -1, { "Unknown", "Unknown" } },
395         };
396         int i;
397
398         for (i = 0; names[i].type != -1; ++i)
399                 if (names[i].type == adp->va_type)
400                         break;
401         return names[i].name[(adp->va_flags & V_ADP_COLOR) ? 0 : 1];
402 }
403
404 static void
405 sctty_outwakeup(struct tty *tp)
406 {
407         size_t len;
408         u_char buf[PCBURST];
409         scr_stat *scp = sc_get_stat(tp);
410
411         if (scp->status & SLKED ||
412             (scp == scp->sc->cur_scp && scp->sc->blink_in_progress))
413                 return;
414
415         for (;;) {
416                 len = ttydisc_getc(tp, buf, sizeof buf);
417                 if (len == 0)
418                         break;
419                 SC_VIDEO_LOCK(scp->sc);
420                 sc_puts(scp, buf, len);
421                 SC_VIDEO_UNLOCK(scp->sc);
422         }
423 }
424
425 static struct tty *
426 sc_alloc_tty(int index, int devnum)
427 {
428         struct sc_ttysoftc *stc;
429         struct tty *tp;
430
431         /* Allocate TTY object and softc to store unit number. */
432         stc = malloc(sizeof(struct sc_ttysoftc), M_DEVBUF, M_WAITOK);
433         stc->st_index = index;
434         stc->st_stat = NULL;
435         tp = tty_alloc_mutex(&sc_ttydevsw, stc, &Giant);
436
437         /* Create device node. */
438         tty_makedev(tp, NULL, "v%r", devnum);
439
440         return (tp);
441 }
442
443 #ifdef SC_PIXEL_MODE
444 static void
445 sc_set_vesa_mode(scr_stat *scp, sc_softc_t *sc, int unit)
446 {
447         video_info_t info;
448         u_char *font;
449         int depth;
450         int fontsize;
451         int i;
452         int vmode;
453
454         vmode = 0;
455         (void)resource_int_value("sc", unit, "vesa_mode", &vmode);
456         if (vmode < M_VESA_BASE || vmode > M_VESA_MODE_MAX ||
457             vidd_get_info(sc->adp, vmode, &info) != 0 ||
458             !sc_support_pixel_mode(&info))
459                 vmode = 0;
460
461         /*
462          * If the mode is unset or unsupported, search for an available
463          * 800x600 graphics mode with the highest color depth.
464          */
465         if (vmode == 0) {
466                 for (depth = 0, i = M_VESA_BASE; i <= M_VESA_MODE_MAX; i++)
467                         if (vidd_get_info(sc->adp, i, &info) == 0 &&
468                             info.vi_width == 800 && info.vi_height == 600 &&
469                             sc_support_pixel_mode(&info) &&
470                             info.vi_depth > depth) {
471                                 vmode = i;
472                                 depth = info.vi_depth;
473                         }
474                 if (vmode == 0)
475                         return;
476                 vidd_get_info(sc->adp, vmode, &info);
477         }
478
479 #if !defined(SC_NO_FONT_LOADING) && defined(SC_DFLT_FONT)
480         fontsize = info.vi_cheight;
481 #else
482         fontsize = scp->font_size;
483 #endif
484         if (fontsize < 14)
485                 fontsize = 8;
486         else if (fontsize >= 16)
487                 fontsize = 16;
488         else
489                 fontsize = 14;
490 #ifndef SC_NO_FONT_LOADING
491         switch (fontsize) {
492         case 8:
493                 if ((sc->fonts_loaded & FONT_8) == 0)
494                         return;
495                 font = sc->font_8;
496                 break;
497         case 14:
498                 if ((sc->fonts_loaded & FONT_14) == 0)
499                         return;
500                 font = sc->font_14;
501                 break;
502         case 16:
503                 if ((sc->fonts_loaded & FONT_16) == 0)
504                         return;
505                 font = sc->font_16;
506                 break;
507         }
508 #else
509         font = NULL;
510 #endif
511 #ifdef DEV_SPLASH
512         if ((sc->flags & SC_SPLASH_SCRN) != 0)
513                 splash_term(sc->adp);
514 #endif
515 #ifndef SC_NO_HISTORY
516         if (scp->history != NULL) {
517                 sc_vtb_append(&scp->vtb, 0, scp->history,
518                     scp->ypos * scp->xsize + scp->xpos);
519                 scp->history_pos = sc_vtb_tail(scp->history);
520         }
521 #endif
522         vidd_set_mode(sc->adp, vmode);
523         scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
524         scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE);
525         scp->xpixel = info.vi_width;
526         scp->ypixel = info.vi_height;
527         scp->xsize = scp->xpixel / 8;
528         scp->ysize = scp->ypixel / fontsize;
529         scp->xpos = 0;
530         scp->ypos = scp->ysize - 1;
531         scp->xoff = scp->yoff = 0;
532         scp->font = font;
533         scp->font_size = fontsize;
534         scp->font_width = 8;
535         scp->start = scp->xsize * scp->ysize - 1;
536         scp->end = 0;
537         scp->cursor_pos = scp->cursor_oldpos = scp->xsize * scp->xsize;
538         scp->mode = sc->initial_mode = vmode;
539 #ifndef __sparc64__
540         sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
541             (void *)sc->adp->va_window, FALSE);
542 #endif
543         sc_alloc_scr_buffer(scp, FALSE, FALSE);
544         sc_init_emulator(scp, NULL);
545 #ifndef SC_NO_CUTPASTE
546         sc_alloc_cut_buffer(scp, FALSE);
547 #endif
548 #ifndef SC_NO_HISTORY
549         sc_alloc_history_buffer(scp, 0, 0, FALSE);
550 #endif
551         sc_set_border(scp, scp->border);
552         sc_set_cursor_image(scp);
553         scp->status &= ~UNKNOWN_MODE;
554 #ifdef DEV_SPLASH
555         if ((sc->flags & SC_SPLASH_SCRN) != 0)
556                 splash_init(sc->adp, scsplash_callback, sc);
557 #endif
558 }
559 #endif
560
561 int
562 sc_attach_unit(int unit, int flags)
563 {
564         sc_softc_t *sc;
565         scr_stat *scp;
566         struct cdev *dev;
567         void *oldts, *ts;
568         int i, vc;
569
570         if (!vty_enabled(VTY_SC))
571                 return ENXIO;
572
573         flags &= ~SC_KERNEL_CONSOLE;
574
575         if (sc_console_unit == unit) {
576                 /*
577                  * If this unit is being used as the system console, we need to
578                  * adjust some variables and buffers before and after scinit().
579                  */
580                 /* assert(sc_console != NULL) */
581                 flags |= SC_KERNEL_CONSOLE;
582                 scmeminit(NULL);
583
584                 scinit(unit, flags);
585
586                 if (sc_console->tsw->te_size > 0) {
587                         sc_ktsw = sc_console->tsw;
588                         /* assert(sc_console->ts != NULL); */
589                         oldts = sc_console->ts;
590                         for (i = 0; i <= mp_maxid; i++) {
591                                 ts = malloc(sc_console->tsw->te_size, M_DEVBUF,
592                                     M_WAITOK | M_ZERO);
593                                 (*sc_console->tsw->te_init)(
594                                     sc_console, &ts, SC_TE_COLD_INIT);
595                                 sc_console->ts = ts;
596                                 (*sc_console->tsw->te_default_attr)(sc_console,
597                                     sc_kattrtab[i], SC_KERNEL_CONS_REV_ATTR);
598                                 sc_kts[i] = ts;
599                         }
600                         sc_console->ts = oldts;
601                         (*sc_console->tsw->te_default_attr)(
602                             sc_console, SC_NORM_ATTR, SC_NORM_REV_ATTR);
603                 }
604         } else {
605                 scinit(unit, flags);
606         }
607
608         sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
609         sc->config = flags;
610         callout_init(&sc->ctimeout, 0);
611         callout_init(&sc->cblink, 0);
612         scp = sc_get_stat(sc->dev[0]);
613         if (sc_console == NULL) /* sc_console_unit < 0 */
614                 sc_console = scp;
615
616 #ifdef SC_PIXEL_MODE
617         if ((sc->config & SC_VESAMODE) != 0)
618                 sc_set_vesa_mode(scp, sc, unit);
619 #endif /* SC_PIXEL_MODE */
620
621         /* initialize cursor */
622         if (!ISGRAPHSC(scp))
623                 update_cursor_image(scp);
624
625         /* get screen update going */
626         scrn_timer(sc);
627
628         /* set up the keyboard */
629         (void)kbdd_ioctl(sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
630         update_kbd_state(scp, scp->status, LOCK_MASK);
631
632         printf("%s%d: %s <%d virtual consoles, flags=0x%x>\n", SC_DRIVER_NAME,
633             unit, adapter_name(sc->adp), sc->vtys, sc->config);
634         if (bootverbose) {
635                 printf("%s%d:", SC_DRIVER_NAME, unit);
636                 if (sc->adapter >= 0)
637                         printf(" fb%d", sc->adapter);
638                 if (sc->keyboard >= 0)
639                         printf(", kbd%d", sc->keyboard);
640                 if (scp->tsw)
641                         printf(", terminal emulator: %s (%s)",
642                             scp->tsw->te_name, scp->tsw->te_desc);
643                 printf("\n");
644         }
645
646         /* Register suspend/resume/shutdown callbacks for the kernel console. */
647         if (sc_console_unit == unit) {
648                 EVENTHANDLER_REGISTER(
649                     power_suspend_early, scsuspend, NULL, EVENTHANDLER_PRI_ANY);
650                 EVENTHANDLER_REGISTER(
651                     power_resume, scresume, NULL, EVENTHANDLER_PRI_ANY);
652                 EVENTHANDLER_REGISTER(
653                     shutdown_pre_sync, scshutdown, NULL, SHUTDOWN_PRI_DEFAULT);
654         }
655
656         for (vc = 0; vc < sc->vtys; vc++) {
657                 if (sc->dev[vc] == NULL) {
658                         sc->dev[vc] = sc_alloc_tty(vc, vc + unit * MAXCONS);
659                         if (vc == 0 && sc->dev == main_devs)
660                                 SC_STAT(sc->dev[0]) = &main_console;
661                 }
662                 /*
663                  * The first vty already has struct tty and scr_stat initialized
664                  * in scinit().  The other vtys will have these structs when
665                  * first opened.
666                  */
667         }
668
669         dev = make_dev(
670             &consolectl_devsw, 0, UID_ROOT, GID_WHEEL, 0600, "consolectl");
671         dev->si_drv1 = sc->dev[0];
672
673         return 0;
674 }
675
676 static void
677 scmeminit(void *arg)
678 {
679         if (!vty_enabled(VTY_SC))
680                 return;
681         if (sc_malloc)
682                 return;
683         sc_malloc = TRUE;
684
685         /*
686          * As soon as malloc() becomes functional, we had better allocate
687          * various buffers for the kernel console.
688          */
689
690         if (sc_console_unit < 0) /* sc_console == NULL */
691                 return;
692
693         /* copy the temporary buffer to the final buffer */
694         sc_alloc_scr_buffer(sc_console, FALSE, FALSE);
695
696 #ifndef SC_NO_CUTPASTE
697         sc_alloc_cut_buffer(sc_console, FALSE);
698 #endif
699
700 #ifndef SC_NO_HISTORY
701         /* initialize history buffer & pointers */
702         sc_alloc_history_buffer(sc_console, 0, 0, FALSE);
703 #endif
704 }
705
706 /* XXX */
707 SYSINIT(sc_mem, SI_SUB_KMEM, SI_ORDER_ANY, scmeminit, NULL);
708
709 static int
710 scdevtounit(struct tty *tp)
711 {
712         int vty = SC_VTY(tp);
713
714         if (vty == SC_CONSOLECTL)
715                 return ((sc_console != NULL) ? sc_console->sc->unit : -1);
716         else if ((vty < 0) || (vty >= MAXCONS * sc_max_unit()))
717                 return -1;
718         else
719                 return vty / MAXCONS;
720 }
721
722 static int
723 sctty_open(struct tty *tp)
724 {
725         int unit = scdevtounit(tp);
726         sc_softc_t *sc;
727         scr_stat *scp;
728 #ifndef __sparc64__
729         keyarg_t key;
730 #endif
731
732         DPRINTF(5,
733             ("scopen: dev:%s, unit:%d, vty:%d\n", devtoname(tp->t_dev), unit,
734                 SC_VTY(tp)));
735
736         sc = sc_get_softc(
737             unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
738         if (sc == NULL)
739                 return ENXIO;
740
741         if (!tty_opened(tp)) {
742                 /* Use the current setting of the <-- key as default VERASE. */
743                 /* If the Delete key is preferable, an stty is necessary     */
744 #ifndef __sparc64__
745                 if (sc->kbd != NULL) {
746                         key.keynum = KEYCODE_BS;
747                         (void)kbdd_ioctl(sc->kbd, GIO_KEYMAPENT, (caddr_t)&key);
748                         tp->t_termios.c_cc[VERASE] = key.key.map[0];
749                 }
750 #endif
751         }
752
753         scp = sc_get_stat(tp);
754         if (scp == NULL) {
755                 scp = SC_STAT(tp) = alloc_scp(sc, SC_VTY(tp));
756                 if (ISGRAPHSC(scp))
757                         sc_set_pixel_mode(scp, NULL, 0, 0, 16, 8);
758         }
759         if (!tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
760                 tp->t_winsize.ws_col = scp->xsize;
761                 tp->t_winsize.ws_row = scp->ysize;
762         }
763
764         return (0);
765 }
766
767 static void
768 sctty_close(struct tty *tp)
769 {
770         scr_stat *scp;
771         int s;
772
773         if (SC_VTY(tp) != SC_CONSOLECTL) {
774                 scp = sc_get_stat(tp);
775                 /* were we in the middle of the VT switching process? */
776                 DPRINTF(5, ("sc%d: scclose(), ", scp->sc->unit));
777                 s = spltty();
778                 if ((scp == scp->sc->cur_scp) &&
779                     (scp->sc->unit == sc_console_unit))
780                         cnavailable(sc_consptr, TRUE);
781                 if (finish_vt_rel(scp, TRUE, &s) == 0) /* force release */
782                         DPRINTF(5, ("reset WAIT_REL, "));
783                 if (finish_vt_acq(scp) == 0) /* force acknowledge */
784                         DPRINTF(5, ("reset WAIT_ACQ, "));
785 #ifdef not_yet_done
786                 if (scp == &main_console) {
787                         scp->pid = 0;
788                         scp->proc = NULL;
789                         scp->smode.mode = VT_AUTO;
790                 } else {
791                         sc_vtb_destroy(&scp->vtb);
792 #ifndef __sparc64__
793                         sc_vtb_destroy(&scp->scr);
794 #endif
795                         sc_free_history_buffer(scp, scp->ysize);
796                         SC_STAT(tp) = NULL;
797                         free(scp, M_DEVBUF);
798                 }
799 #else
800                 scp->pid = 0;
801                 scp->proc = NULL;
802                 scp->smode.mode = VT_AUTO;
803 #endif
804                 scp->kbd_mode = K_XLATE;
805                 if (scp == scp->sc->cur_scp)
806                         (void)kbdd_ioctl(
807                             scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
808                 DPRINTF(5, ("done.\n"));
809         }
810 }
811
812 #if 0 /* XXX mpsafetty: fix screensaver. What about outwakeup? */
813 static int
814 scread(struct cdev *dev, struct uio *uio, int flag)
815 {
816     if (!sc_saver_keyb_only)
817         sc_touch_scrn_saver();
818     return ttyread(dev, uio, flag);
819 }
820 #endif
821
822 static int
823 sckbdevent(keyboard_t *thiskbd, int event, void *arg)
824 {
825         sc_softc_t *sc;
826         struct tty *cur_tty;
827         int c, error = 0;
828         size_t len;
829         const u_char *cp;
830
831         sc = (sc_softc_t *)arg;
832         /* assert(thiskbd == sc->kbd) */
833
834         mtx_lock(&Giant);
835
836         switch (event) {
837         case KBDIO_KEYINPUT:
838                 break;
839         case KBDIO_UNLOADING:
840                 sc->kbd = NULL;
841                 sc->keyboard = -1;
842                 kbd_release(thiskbd, (void *)&sc->keyboard);
843                 goto done;
844         default:
845                 error = EINVAL;
846                 goto done;
847         }
848
849         /*
850          * Loop while there is still input to get from the keyboard.
851          * I don't think this is nessesary, and it doesn't fix
852          * the Xaccel-2.1 keyboard hang, but it can't hurt.             XXX
853          */
854         while ((c = scgetc(sc, SCGETC_NONBLOCK, NULL)) != NOKEY) {
855
856                 cur_tty = SC_DEV(sc, sc->cur_scp->index);
857                 if (!tty_opened_ns(cur_tty))
858                         continue;
859
860                 if ((*sc->cur_scp->tsw->te_input)(sc->cur_scp, c, cur_tty))
861                         continue;
862
863                 switch (KEYFLAGS(c)) {
864                 case 0x0000: /* normal key */
865                         ttydisc_rint(cur_tty, KEYCHAR(c), 0);
866                         break;
867                 case FKEY: /* function key, return string */
868                         cp = (*sc->cur_scp->tsw->te_fkeystr)(sc->cur_scp, c);
869                         if (cp != NULL) {
870                                 ttydisc_rint_simple(cur_tty, cp, strlen(cp));
871                                 break;
872                         }
873                         cp = kbdd_get_fkeystr(thiskbd, KEYCHAR(c), &len);
874                         if (cp != NULL)
875                                 ttydisc_rint_simple(cur_tty, cp, len);
876                         break;
877                 case MKEY: /* meta is active, prepend ESC */
878                         ttydisc_rint(cur_tty, 0x1b, 0);
879                         ttydisc_rint(cur_tty, KEYCHAR(c), 0);
880                         break;
881                 case BKEY: /* backtab fixed sequence (esc [ Z) */
882                         ttydisc_rint_simple(cur_tty, "\x1B[Z", 3);
883                         break;
884                 }
885
886                 ttydisc_rint_done(cur_tty);
887         }
888
889         sc->cur_scp->status |= MOUSE_HIDDEN;
890
891 done:
892         mtx_unlock(&Giant);
893         return (error);
894 }
895
896 static int
897 sctty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
898 {
899         int error;
900         int i;
901         struct cursor_attr *cap;
902         sc_softc_t *sc;
903         scr_stat *scp;
904         int s;
905 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
906     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
907         int ival;
908 #endif
909
910         /* If there is a user_ioctl function call that first */
911         if (sc_user_ioctl) {
912                 error = (*sc_user_ioctl)(tp, cmd, data, td);
913                 if (error != ENOIOCTL)
914                         return error;
915         }
916
917         error = sc_vid_ioctl(tp, cmd, data, td);
918         if (error != ENOIOCTL)
919                 return error;
920
921 #ifndef SC_NO_HISTORY
922         error = sc_hist_ioctl(tp, cmd, data, td);
923         if (error != ENOIOCTL)
924                 return error;
925 #endif
926
927 #ifndef SC_NO_SYSMOUSE
928         error = sc_mouse_ioctl(tp, cmd, data, td);
929         if (error != ENOIOCTL)
930                 return error;
931 #endif
932
933         scp = sc_get_stat(tp);
934         /* assert(scp != NULL) */
935         /* scp is sc_console, if SC_VTY(dev) == SC_CONSOLECTL. */
936         sc = scp->sc;
937
938         if (scp->tsw) {
939                 error = (*scp->tsw->te_ioctl)(scp, tp, cmd, data, td);
940                 if (error != ENOIOCTL)
941                         return error;
942         }
943
944         switch (cmd) { /* process console hardware related ioctl's */
945
946         case GIO_ATTR: /* get current attributes */
947                 /* this ioctl is not processed here, but in the terminal
948                  * emulator */
949                 return ENOTTY;
950
951         case GIO_COLOR: /* is this a color console ? */
952                 *(int *)data = (sc->adp->va_flags & V_ADP_COLOR) ? 1 : 0;
953                 return 0;
954
955         case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */
956                 if (*(int *)data < 0 || *(int *)data > MAX_BLANKTIME)
957                         return EINVAL;
958                 s = spltty();
959                 scrn_blank_time = *(int *)data;
960                 run_scrn_saver = (scrn_blank_time != 0);
961                 splx(s);
962                 return 0;
963
964         case CONS_CURSORTYPE: /* set cursor type (old interface + HIDDEN) */
965                 s = spltty();
966                 *(int *)data &= CONS_CURSOR_ATTRS;
967                 sc_change_cursor_shape(scp, *(int *)data, -1, -1);
968                 splx(s);
969                 return 0;
970
971         case CONS_GETCURSORSHAPE: /* get cursor shape (new interface) */
972                 switch (((int *)data)[0] &
973                     (CONS_DEFAULT_CURSOR | CONS_LOCAL_CURSOR)) {
974                 case 0:
975                         cap = &sc->curs_attr;
976                         break;
977                 case CONS_LOCAL_CURSOR:
978                         cap = &scp->base_curs_attr;
979                         break;
980                 case CONS_DEFAULT_CURSOR:
981                         cap = &sc->dflt_curs_attr;
982                         break;
983                 case CONS_DEFAULT_CURSOR | CONS_LOCAL_CURSOR:
984                         cap = &scp->dflt_curs_attr;
985                         break;
986                 }
987                 if (((int *)data)[0] & CONS_CHARCURSOR_COLORS) {
988                         ((int *)data)[1] = cap->bg[0];
989                         ((int *)data)[2] = cap->bg[1];
990                 } else if (((int *)data)[0] & CONS_MOUSECURSOR_COLORS) {
991                         ((int *)data)[1] = cap->mouse_ba;
992                         ((int *)data)[2] = cap->mouse_ia;
993                 } else {
994                         ((int *)data)[1] = cap->base;
995                         ((int *)data)[2] = cap->height;
996                 }
997                 ((int *)data)[0] = cap->flags;
998                 return 0;
999
1000         case CONS_SETCURSORSHAPE: /* set cursor shape (new interface) */
1001                 s = spltty();
1002                 sc_change_cursor_shape(
1003                     scp, ((int *)data)[0], ((int *)data)[1], ((int *)data)[2]);
1004                 splx(s);
1005                 return 0;
1006
1007         case CONS_BELLTYPE: /* set bell type sound/visual */
1008                 if ((*(int *)data) & CONS_VISUAL_BELL)
1009                         sc->flags |= SC_VISUAL_BELL;
1010                 else
1011                         sc->flags &= ~SC_VISUAL_BELL;
1012                 if ((*(int *)data) & CONS_QUIET_BELL)
1013                         sc->flags |= SC_QUIET_BELL;
1014                 else
1015                         sc->flags &= ~SC_QUIET_BELL;
1016                 return 0;
1017
1018         case CONS_GETINFO: /* get current (virtual) console info */
1019         {
1020                 vid_info_t *ptr = (vid_info_t *)data;
1021                 if (ptr->size == sizeof(struct vid_info)) {
1022                         ptr->m_num = sc->cur_scp->index;
1023                         ptr->font_size = scp->font_size;
1024                         ptr->mv_col = scp->xpos;
1025                         ptr->mv_row = scp->ypos;
1026                         ptr->mv_csz = scp->xsize;
1027                         ptr->mv_rsz = scp->ysize;
1028                         ptr->mv_hsz =
1029                             (scp->history != NULL) ? scp->history->vtb_rows : 0;
1030                         /*
1031                          * The following fields are filled by the terminal
1032                          * emulator. XXX
1033                          *
1034                          * ptr->mv_norm.fore
1035                          * ptr->mv_norm.back
1036                          * ptr->mv_rev.fore
1037                          * ptr->mv_rev.back
1038                          */
1039                         ptr->mv_grfc.fore = 0; /* not supported */
1040                         ptr->mv_grfc.back = 0; /* not supported */
1041                         ptr->mv_ovscan = scp->border;
1042                         if (scp == sc->cur_scp)
1043                                 save_kbd_state(scp);
1044                         ptr->mk_keylock = scp->status & LOCK_MASK;
1045                         return 0;
1046                 }
1047                 return EINVAL;
1048         }
1049
1050         case CONS_GETVERS: /* get version number */
1051                 *(int *)data = 0x200; /* version 2.0 */
1052                 return 0;
1053
1054         case CONS_IDLE: /* see if the screen has been idle */
1055                 /*
1056                  * When the screen is in the GRAPHICS_MODE or UNKNOWN_MODE,
1057                  * the user process may have been writing something on the
1058                  * screen and syscons is not aware of it. Declare the screen
1059                  * is NOT idle if it is in one of these modes. But there is
1060                  * an exception to it; if a screen saver is running in the
1061                  * graphics mode in the current screen, we should say that the
1062                  * screen has been idle.
1063                  */
1064                 *(int *)data = (sc->flags & SC_SCRN_IDLE) &&
1065                     (!ISGRAPHSC(sc->cur_scp) ||
1066                         (sc->cur_scp->status & SAVER_RUNNING));
1067                 return 0;
1068
1069         case CONS_SAVERMODE: /* set saver mode */
1070                 switch (*(int *)data) {
1071                 case CONS_NO_SAVER:
1072                 case CONS_USR_SAVER:
1073                         /* if a LKM screen saver is running, stop it first. */
1074                         scsplash_stick(FALSE);
1075                         saver_mode = *(int *)data;
1076                         s = spltty();
1077 #ifdef DEV_SPLASH
1078                         if ((error = wait_scrn_saver_stop(NULL))) {
1079                                 splx(s);
1080                                 return error;
1081                         }
1082 #endif
1083                         run_scrn_saver = TRUE;
1084                         if (saver_mode == CONS_USR_SAVER)
1085                                 scp->status |= SAVER_RUNNING;
1086                         else
1087                                 scp->status &= ~SAVER_RUNNING;
1088                         scsplash_stick(TRUE);
1089                         splx(s);
1090                         break;
1091                 case CONS_LKM_SAVER:
1092                         s = spltty();
1093                         if ((saver_mode == CONS_USR_SAVER) &&
1094                             (scp->status & SAVER_RUNNING))
1095                                 scp->status &= ~SAVER_RUNNING;
1096                         saver_mode = *(int *)data;
1097                         splx(s);
1098                         break;
1099                 default:
1100                         return EINVAL;
1101                 }
1102                 return 0;
1103
1104         case CONS_SAVERSTART: /* immediately start/stop the screen saver */
1105                 /*
1106                  * Note that this ioctl does not guarantee the screen saver
1107                  * actually starts or stops. It merely attempts to do so...
1108                  */
1109                 s = spltty();
1110                 run_scrn_saver = (*(int *)data != 0);
1111                 if (run_scrn_saver)
1112                         sc->scrn_time_stamp -= scrn_blank_time;
1113                 splx(s);
1114                 return 0;
1115
1116         case CONS_SCRSHOT: /* get a screen shot */
1117         {
1118                 int retval, hist_rsz;
1119                 size_t lsize, csize;
1120                 vm_offset_t frbp, hstp;
1121                 unsigned lnum;
1122                 scrshot_t *ptr = (scrshot_t *)data;
1123                 void *outp = ptr->buf;
1124
1125                 if (ptr->x < 0 || ptr->y < 0 || ptr->xsize < 0 ||
1126                     ptr->ysize < 0)
1127                         return EINVAL;
1128                 s = spltty();
1129                 if (ISGRAPHSC(scp)) {
1130                         splx(s);
1131                         return EOPNOTSUPP;
1132                 }
1133                 hist_rsz = (scp->history != NULL) ? scp->history->vtb_rows : 0;
1134                 if (((u_int)ptr->x + ptr->xsize) > scp->xsize ||
1135                     ((u_int)ptr->y + ptr->ysize) > (scp->ysize + hist_rsz)) {
1136                         splx(s);
1137                         return EINVAL;
1138                 }
1139
1140                 lsize = scp->xsize * sizeof(u_int16_t);
1141                 csize = ptr->xsize * sizeof(u_int16_t);
1142                 /* Pointer to the last line of framebuffer */
1143                 frbp = scp->vtb.vtb_buffer + scp->ysize * lsize +
1144                     ptr->x * sizeof(u_int16_t);
1145                 /* Pointer to the last line of target buffer */
1146                 outp = (char *)outp + ptr->ysize * csize;
1147                 /* Pointer to the last line of history buffer */
1148                 if (scp->history != NULL)
1149                         hstp = scp->history->vtb_buffer +
1150                             sc_vtb_tail(scp->history) * sizeof(u_int16_t) +
1151                             ptr->x * sizeof(u_int16_t);
1152                 else
1153                         hstp = 0;
1154
1155                 retval = 0;
1156                 for (lnum = 0; lnum < (ptr->y + ptr->ysize); lnum++) {
1157                         if (lnum < scp->ysize) {
1158                                 frbp -= lsize;
1159                         } else {
1160                                 hstp -= lsize;
1161                                 if (hstp < scp->history->vtb_buffer)
1162                                         hstp += scp->history->vtb_rows * lsize;
1163                                 frbp = hstp;
1164                         }
1165                         if (lnum < ptr->y)
1166                                 continue;
1167                         outp = (char *)outp - csize;
1168                         retval = copyout((void *)frbp, outp, csize);
1169                         if (retval != 0)
1170                                 break;
1171                 }
1172                 splx(s);
1173                 return retval;
1174         }
1175
1176         case VT_SETMODE: /* set screen switcher mode */
1177         {
1178                 struct vt_mode *mode;
1179                 struct proc *p1;
1180
1181                 mode = (struct vt_mode *)data;
1182                 DPRINTF(5, ("%s%d: VT_SETMODE ", SC_DRIVER_NAME, sc->unit));
1183                 if (scp->smode.mode == VT_PROCESS) {
1184                         p1 = pfind(scp->pid);
1185                         if (scp->proc == p1 && scp->proc != td->td_proc) {
1186                                 if (p1)
1187                                         PROC_UNLOCK(p1);
1188                                 DPRINTF(5, ("error EPERM\n"));
1189                                 return EPERM;
1190                         }
1191                         if (p1)
1192                                 PROC_UNLOCK(p1);
1193                 }
1194                 s = spltty();
1195                 if (mode->mode == VT_AUTO) {
1196                         scp->smode.mode = VT_AUTO;
1197                         scp->proc = NULL;
1198                         scp->pid = 0;
1199                         DPRINTF(5, ("VT_AUTO, "));
1200                         if ((scp == sc->cur_scp) &&
1201                             (sc->unit == sc_console_unit))
1202                                 cnavailable(sc_consptr, TRUE);
1203                         /* were we in the middle of the vty switching process?
1204                          */
1205                         if (finish_vt_rel(scp, TRUE, &s) == 0)
1206                                 DPRINTF(5, ("reset WAIT_REL, "));
1207                         if (finish_vt_acq(scp) == 0)
1208                                 DPRINTF(5, ("reset WAIT_ACQ, "));
1209                 } else {
1210                         if (!ISSIGVALID(mode->relsig) ||
1211                             !ISSIGVALID(mode->acqsig) ||
1212                             !ISSIGVALID(mode->frsig)) {
1213                                 splx(s);
1214                                 DPRINTF(5, ("error EINVAL\n"));
1215                                 return EINVAL;
1216                         }
1217                         DPRINTF(5, ("VT_PROCESS %d, ", td->td_proc->p_pid));
1218                         bcopy(data, &scp->smode, sizeof(struct vt_mode));
1219                         scp->proc = td->td_proc;
1220                         scp->pid = scp->proc->p_pid;
1221                         if ((scp == sc->cur_scp) &&
1222                             (sc->unit == sc_console_unit))
1223                                 cnavailable(sc_consptr, FALSE);
1224                 }
1225                 splx(s);
1226                 DPRINTF(5, ("\n"));
1227                 return 0;
1228         }
1229
1230         case VT_GETMODE: /* get screen switcher mode */
1231                 bcopy(&scp->smode, data, sizeof(struct vt_mode));
1232                 return 0;
1233
1234 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1235     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1236         case _IO('v', 4):
1237                 ival = IOCPARM_IVAL(data);
1238                 data = (caddr_t)&ival;
1239                 /* FALLTHROUGH */
1240 #endif
1241         case VT_RELDISP: /* screen switcher ioctl */
1242                 s = spltty();
1243                 /*
1244                  * This must be the current vty which is in the VT_PROCESS
1245                  * switching mode...
1246                  */
1247                 if ((scp != sc->cur_scp) || (scp->smode.mode != VT_PROCESS)) {
1248                         splx(s);
1249                         return EINVAL;
1250                 }
1251                 /* ...and this process is controlling it. */
1252                 if (scp->proc != td->td_proc) {
1253                         splx(s);
1254                         return EPERM;
1255                 }
1256                 error = EINVAL;
1257                 switch (*(int *)data) {
1258                 case VT_FALSE: /* user refuses to release screen, abort */
1259                         if ((error = finish_vt_rel(scp, FALSE, &s)) == 0)
1260                                 DPRINTF(5,
1261                                     ("%s%d: VT_FALSE\n", SC_DRIVER_NAME,
1262                                         sc->unit));
1263                         break;
1264                 case VT_TRUE: /* user has released screen, go on */
1265                         if ((error = finish_vt_rel(scp, TRUE, &s)) == 0)
1266                                 DPRINTF(5,
1267                                     ("%s%d: VT_TRUE\n", SC_DRIVER_NAME,
1268                                         sc->unit));
1269                         break;
1270                 case VT_ACKACQ: /* acquire acknowledged, switch completed */
1271                         if ((error = finish_vt_acq(scp)) == 0)
1272                                 DPRINTF(5,
1273                                     ("%s%d: VT_ACKACQ\n", SC_DRIVER_NAME,
1274                                         sc->unit));
1275                         break;
1276                 default:
1277                         break;
1278                 }
1279                 splx(s);
1280                 return error;
1281
1282         case VT_OPENQRY: /* return free virtual console */
1283                 for (i = sc->first_vty; i < sc->first_vty + sc->vtys; i++) {
1284                         tp = SC_DEV(sc, i);
1285                         if (!tty_opened_ns(tp)) {
1286                                 *(int *)data = i + 1;
1287                                 return 0;
1288                         }
1289                 }
1290                 return EINVAL;
1291
1292 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1293     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1294         case _IO('v', 5):
1295                 ival = IOCPARM_IVAL(data);
1296                 data = (caddr_t)&ival;
1297                 /* FALLTHROUGH */
1298 #endif
1299         case VT_ACTIVATE: /* switch to screen *data */
1300                 i = (*(int *)data == 0) ? scp->index : (*(int *)data - 1);
1301                 s = spltty();
1302                 error = sc_clean_up(sc->cur_scp);
1303                 splx(s);
1304                 if (error)
1305                         return error;
1306                 error = sc_switch_scr(sc, i);
1307                 return (error);
1308
1309 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1310     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1311         case _IO('v', 6):
1312                 ival = IOCPARM_IVAL(data);
1313                 data = (caddr_t)&ival;
1314                 /* FALLTHROUGH */
1315 #endif
1316         case VT_WAITACTIVE: /* wait for switch to occur */
1317                 i = (*(int *)data == 0) ? scp->index : (*(int *)data - 1);
1318                 if ((i < sc->first_vty) || (i >= sc->first_vty + sc->vtys))
1319                         return EINVAL;
1320                 if (i == sc->cur_scp->index)
1321                         return 0;
1322                 error =
1323                     tsleep(VTY_WCHAN(sc, i), (PZERO + 1) | PCATCH, "waitvt", 0);
1324                 return error;
1325
1326         case VT_GETACTIVE: /* get active vty # */
1327                 *(int *)data = sc->cur_scp->index + 1;
1328                 return 0;
1329
1330         case VT_GETINDEX: /* get this vty # */
1331                 *(int *)data = scp->index + 1;
1332                 return 0;
1333
1334         case VT_LOCKSWITCH: /* prevent vty switching */
1335                 if ((*(int *)data) & 0x01)
1336                         sc->flags |= SC_SCRN_VTYLOCK;
1337                 else
1338                         sc->flags &= ~SC_SCRN_VTYLOCK;
1339                 return 0;
1340
1341         case KDENABIO: /* allow io operations */
1342                 error = priv_check(td, PRIV_IO);
1343                 if (error != 0)
1344                         return error;
1345                 error = securelevel_gt(td->td_ucred, 0);
1346                 if (error != 0)
1347                         return error;
1348 #ifdef __i386__
1349                 td->td_frame->tf_eflags |= PSL_IOPL;
1350 #elif defined(__amd64__)
1351                 td->td_frame->tf_rflags |= PSL_IOPL;
1352 #endif
1353                 return 0;
1354
1355         case KDDISABIO: /* disallow io operations (default) */
1356 #ifdef __i386__
1357                 td->td_frame->tf_eflags &= ~PSL_IOPL;
1358 #elif defined(__amd64__)
1359                 td->td_frame->tf_rflags &= ~PSL_IOPL;
1360 #endif
1361                 return 0;
1362
1363 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1364     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1365         case _IO('K', 20):
1366                 ival = IOCPARM_IVAL(data);
1367                 data = (caddr_t)&ival;
1368                 /* FALLTHROUGH */
1369 #endif
1370         case KDSKBSTATE: /* set keyboard state (locks) */
1371                 if (*(int *)data & ~LOCK_MASK)
1372                         return EINVAL;
1373                 scp->status &= ~LOCK_MASK;
1374                 scp->status |= *(int *)data;
1375                 if (scp == sc->cur_scp)
1376                         update_kbd_state(scp, scp->status, LOCK_MASK);
1377                 return 0;
1378
1379         case KDGKBSTATE: /* get keyboard state (locks) */
1380                 if (scp == sc->cur_scp)
1381                         save_kbd_state(scp);
1382                 *(int *)data = scp->status & LOCK_MASK;
1383                 return 0;
1384
1385         case KDGETREPEAT: /* get keyboard repeat & delay rates */
1386         case KDSETREPEAT: /* set keyboard repeat & delay rates (new) */
1387                 error = kbdd_ioctl(sc->kbd, cmd, data);
1388                 if (error == ENOIOCTL)
1389                         error = ENODEV;
1390                 return error;
1391
1392 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1393     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1394         case _IO('K', 67):
1395                 ival = IOCPARM_IVAL(data);
1396                 data = (caddr_t)&ival;
1397                 /* FALLTHROUGH */
1398 #endif
1399         case KDSETRAD: /* set keyboard repeat & delay rates (old) */
1400                 if (*(int *)data & ~0x7f)
1401                         return EINVAL;
1402                 error = kbdd_ioctl(sc->kbd, KDSETRAD, data);
1403                 if (error == ENOIOCTL)
1404                         error = ENODEV;
1405                 return error;
1406
1407 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1408     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1409         case _IO('K', 7):
1410                 ival = IOCPARM_IVAL(data);
1411                 data = (caddr_t)&ival;
1412                 /* FALLTHROUGH */
1413 #endif
1414         case KDSKBMODE: /* set keyboard mode */
1415                 switch (*(int *)data) {
1416                 case K_XLATE: /* switch to XLT ascii mode */
1417                 case K_RAW: /* switch to RAW scancode mode */
1418                 case K_CODE: /* switch to CODE mode */
1419                         scp->kbd_mode = *(int *)data;
1420                         if (scp == sc->cur_scp)
1421                                 (void)kbdd_ioctl(sc->kbd, KDSKBMODE, data);
1422                         return 0;
1423                 default:
1424                         return EINVAL;
1425                 }
1426                 /* NOT REACHED */
1427
1428         case KDGKBMODE: /* get keyboard mode */
1429                 *(int *)data = scp->kbd_mode;
1430                 return 0;
1431
1432         case KDGKBINFO:
1433                 error = kbdd_ioctl(sc->kbd, cmd, data);
1434                 if (error == ENOIOCTL)
1435                         error = ENODEV;
1436                 return error;
1437
1438 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1439     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1440         case _IO('K', 8):
1441                 ival = IOCPARM_IVAL(data);
1442                 data = (caddr_t)&ival;
1443                 /* FALLTHROUGH */
1444 #endif
1445         case KDMKTONE: /* sound the bell */
1446                 if (*(int *)data)
1447                         sc_bell(scp, (*(int *)data) & 0xffff,
1448                             (((*(int *)data) >> 16) & 0xffff) * hz / 1000);
1449                 else
1450                         sc_bell(scp, scp->bell_pitch, scp->bell_duration);
1451                 return 0;
1452
1453 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1454     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1455         case _IO('K', 63):
1456                 ival = IOCPARM_IVAL(data);
1457                 data = (caddr_t)&ival;
1458                 /* FALLTHROUGH */
1459 #endif
1460         case KIOCSOUND: /* make tone (*data) hz */
1461                 if (scp == sc->cur_scp) {
1462                         if (*(int *)data)
1463                                 return sc_tone(*(int *)data);
1464                         else
1465                                 return sc_tone(0);
1466                 }
1467                 return 0;
1468
1469         case KDGKBTYPE: /* get keyboard type */
1470                 error = kbdd_ioctl(sc->kbd, cmd, data);
1471                 if (error == ENOIOCTL) {
1472                         /* always return something? XXX */
1473                         *(int *)data = 0;
1474                 }
1475                 return 0;
1476
1477 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1478     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1479         case _IO('K', 66):
1480                 ival = IOCPARM_IVAL(data);
1481                 data = (caddr_t)&ival;
1482                 /* FALLTHROUGH */
1483 #endif
1484         case KDSETLED: /* set keyboard LED status */
1485                 if (*(int *)data & ~LED_MASK) /* FIXME: LOCK_MASK? */
1486                         return EINVAL;
1487                 scp->status &= ~LED_MASK;
1488                 scp->status |= *(int *)data;
1489                 if (scp == sc->cur_scp)
1490                         update_kbd_leds(scp, scp->status);
1491                 return 0;
1492
1493         case KDGETLED: /* get keyboard LED status */
1494                 if (scp == sc->cur_scp)
1495                         save_kbd_state(scp);
1496                 *(int *)data = scp->status & LED_MASK;
1497                 return 0;
1498
1499         case KBADDKBD: /* add/remove keyboard to/from mux */
1500         case KBRELKBD:
1501                 error = kbdd_ioctl(sc->kbd, cmd, data);
1502                 if (error == ENOIOCTL)
1503                         error = ENODEV;
1504                 return error;
1505
1506 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1507     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1508         case _IO('c', 110):
1509                 ival = IOCPARM_IVAL(data);
1510                 data = (caddr_t)&ival;
1511                 /* FALLTHROUGH */
1512 #endif
1513         case CONS_SETKBD: /* set the new keyboard */
1514         {
1515                 keyboard_t *newkbd;
1516
1517                 s = spltty();
1518                 newkbd = kbd_get_keyboard(*(int *)data);
1519                 if (newkbd == NULL) {
1520                         splx(s);
1521                         return EINVAL;
1522                 }
1523                 error = 0;
1524                 if (sc->kbd != newkbd) {
1525                         i = kbd_allocate(newkbd->kb_name, newkbd->kb_unit,
1526                             (void *)&sc->keyboard, sckbdevent, sc);
1527                         /* i == newkbd->kb_index */
1528                         if (i >= 0) {
1529                                 if (sc->kbd != NULL) {
1530                                         save_kbd_state(sc->cur_scp);
1531                                         kbd_release(
1532                                             sc->kbd, (void *)&sc->keyboard);
1533                                 }
1534                                 sc->kbd =
1535                                     kbd_get_keyboard(i); /* sc->kbd == newkbd */
1536                                 sc->keyboard = i;
1537                                 (void)kbdd_ioctl(sc->kbd, KDSKBMODE,
1538                                     (caddr_t)&sc->cur_scp->kbd_mode);
1539                                 update_kbd_state(sc->cur_scp,
1540                                     sc->cur_scp->status, LOCK_MASK);
1541                         } else {
1542                                 error = EPERM; /* XXX */
1543                         }
1544                 }
1545                 splx(s);
1546                 return error;
1547         }
1548
1549         case CONS_RELKBD: /* release the current keyboard */
1550                 s = spltty();
1551                 error = 0;
1552                 if (sc->kbd != NULL) {
1553                         save_kbd_state(sc->cur_scp);
1554                         error = kbd_release(sc->kbd, (void *)&sc->keyboard);
1555                         if (error == 0) {
1556                                 sc->kbd = NULL;
1557                                 sc->keyboard = -1;
1558                         }
1559                 }
1560                 splx(s);
1561                 return error;
1562
1563         case CONS_GETTERM: /* get the current terminal emulator info */
1564         {
1565                 sc_term_sw_t *sw;
1566
1567                 if (((term_info_t *)data)->ti_index == 0) {
1568                         sw = scp->tsw;
1569                 } else {
1570                         sw = sc_term_match_by_number(
1571                             ((term_info_t *)data)->ti_index);
1572                 }
1573                 if (sw != NULL) {
1574                         strncpy(((term_info_t *)data)->ti_name, sw->te_name,
1575                             sizeof(((term_info_t *)data)->ti_name));
1576                         strncpy(((term_info_t *)data)->ti_desc, sw->te_desc,
1577                             sizeof(((term_info_t *)data)->ti_desc));
1578                         ((term_info_t *)data)->ti_flags = 0;
1579                         return 0;
1580                 } else {
1581                         ((term_info_t *)data)->ti_name[0] = '\0';
1582                         ((term_info_t *)data)->ti_desc[0] = '\0';
1583                         ((term_info_t *)data)->ti_flags = 0;
1584                         return EINVAL;
1585                 }
1586         }
1587
1588         case CONS_SETTERM: /* set the current terminal emulator */
1589                 s = spltty();
1590                 error = sc_init_emulator(scp, ((term_info_t *)data)->ti_name);
1591                 /* FIXME: what if scp == sc_console! XXX */
1592                 splx(s);
1593                 return error;
1594
1595         case GIO_SCRNMAP: /* get output translation table */
1596                 bcopy(&sc->scr_map, data, sizeof(sc->scr_map));
1597                 return 0;
1598
1599         case PIO_SCRNMAP: /* set output translation table */
1600                 bcopy(data, &sc->scr_map, sizeof(sc->scr_map));
1601                 for (i = 0; i < sizeof(sc->scr_map); i++) {
1602                         sc->scr_rmap[sc->scr_map[i]] = i;
1603                 }
1604                 return 0;
1605
1606         case GIO_KEYMAP: /* get keyboard translation table */
1607         case PIO_KEYMAP: /* set keyboard translation table */
1608         case OGIO_KEYMAP: /* get keyboard translation table (compat) */
1609         case OPIO_KEYMAP: /* set keyboard translation table (compat) */
1610         case GIO_DEADKEYMAP: /* get accent key translation table */
1611         case PIO_DEADKEYMAP: /* set accent key translation table */
1612         case GETFKEY: /* get function key string */
1613         case SETFKEY: /* set function key string */
1614                 error = kbdd_ioctl(sc->kbd, cmd, data);
1615                 if (error == ENOIOCTL)
1616                         error = ENODEV;
1617                 return error;
1618
1619 #ifndef SC_NO_FONT_LOADING
1620
1621         case PIO_FONT8x8: /* set 8x8 dot font */
1622                 if (!ISFONTAVAIL(sc->adp->va_flags))
1623                         return ENXIO;
1624                 bcopy(data, sc->font_8, 8 * 256);
1625                 sc->fonts_loaded |= FONT_8;
1626                 /*
1627                  * FONT KLUDGE
1628                  * Always use the font page #0. XXX
1629                  * Don't load if the current font size is not 8x8.
1630                  */
1631                 if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size < 14))
1632                         sc_load_font(sc->cur_scp, 0, 8, 8, sc->font_8, 0, 256);
1633                 return 0;
1634
1635         case GIO_FONT8x8: /* get 8x8 dot font */
1636                 if (!ISFONTAVAIL(sc->adp->va_flags))
1637                         return ENXIO;
1638                 if (sc->fonts_loaded & FONT_8) {
1639                         bcopy(sc->font_8, data, 8 * 256);
1640                         return 0;
1641                 } else
1642                         return ENXIO;
1643
1644         case PIO_FONT8x14: /* set 8x14 dot font */
1645                 if (!ISFONTAVAIL(sc->adp->va_flags))
1646                         return ENXIO;
1647                 bcopy(data, sc->font_14, 14 * 256);
1648                 sc->fonts_loaded |= FONT_14;
1649                 /*
1650                  * FONT KLUDGE
1651                  * Always use the font page #0. XXX
1652                  * Don't load if the current font size is not 8x14.
1653                  */
1654                 if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size >= 14) &&
1655                     (sc->cur_scp->font_size < 16))
1656                         sc_load_font(
1657                             sc->cur_scp, 0, 14, 8, sc->font_14, 0, 256);
1658                 return 0;
1659
1660         case GIO_FONT8x14: /* get 8x14 dot font */
1661                 if (!ISFONTAVAIL(sc->adp->va_flags))
1662                         return ENXIO;
1663                 if (sc->fonts_loaded & FONT_14) {
1664                         bcopy(sc->font_14, data, 14 * 256);
1665                         return 0;
1666                 } else
1667                         return ENXIO;
1668
1669         case PIO_FONT8x16: /* set 8x16 dot font */
1670                 if (!ISFONTAVAIL(sc->adp->va_flags))
1671                         return ENXIO;
1672                 bcopy(data, sc->font_16, 16 * 256);
1673                 sc->fonts_loaded |= FONT_16;
1674                 /*
1675                  * FONT KLUDGE
1676                  * Always use the font page #0. XXX
1677                  * Don't load if the current font size is not 8x16.
1678                  */
1679                 if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size >= 16))
1680                         sc_load_font(
1681                             sc->cur_scp, 0, 16, 8, sc->font_16, 0, 256);
1682                 return 0;
1683
1684         case GIO_FONT8x16: /* get 8x16 dot font */
1685                 if (!ISFONTAVAIL(sc->adp->va_flags))
1686                         return ENXIO;
1687                 if (sc->fonts_loaded & FONT_16) {
1688                         bcopy(sc->font_16, data, 16 * 256);
1689                         return 0;
1690                 } else
1691                         return ENXIO;
1692
1693 #endif /* SC_NO_FONT_LOADING */
1694
1695         default:
1696                 break;
1697         }
1698
1699         return (ENOIOCTL);
1700 }
1701
1702 static int
1703 consolectl_ioctl(
1704     struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
1705 {
1706
1707         return sctty_ioctl(dev->si_drv1, cmd, data, td);
1708 }
1709
1710 static int
1711 consolectl_close(struct cdev *dev, int flags, int mode, struct thread *td)
1712 {
1713 #ifndef SC_NO_SYSMOUSE
1714         mouse_info_t info;
1715         memset(&info, 0, sizeof(info));
1716         info.operation = MOUSE_ACTION;
1717
1718         /*
1719          * Make sure all buttons are released when moused and other
1720          * console daemons exit, so that no buttons are left pressed.
1721          */
1722         (void)sctty_ioctl(dev->si_drv1, CONS_MOUSECTL, (caddr_t)&info, td);
1723 #endif
1724         return (0);
1725 }
1726
1727 static void
1728 sc_cnprobe(struct consdev *cp)
1729 {
1730         int unit;
1731         int flags;
1732
1733         if (!vty_enabled(VTY_SC)) {
1734                 cp->cn_pri = CN_DEAD;
1735                 return;
1736         }
1737
1738         cp->cn_pri = sc_get_cons_priority(&unit, &flags);
1739
1740         /* a video card is always required */
1741         if (!scvidprobe(unit, flags, TRUE))
1742                 cp->cn_pri = CN_DEAD;
1743
1744         /* syscons will become console even when there is no keyboard */
1745         sckbdprobe(unit, flags, TRUE);
1746
1747         if (cp->cn_pri == CN_DEAD)
1748                 return;
1749
1750         /* initialize required fields */
1751         strcpy(cp->cn_name, "ttyv0");
1752 }
1753
1754 static void
1755 sc_cninit(struct consdev *cp)
1756 {
1757         int unit;
1758         int flags;
1759
1760         sc_get_cons_priority(&unit, &flags);
1761         scinit(unit, flags | SC_KERNEL_CONSOLE);
1762         sc_console_unit = unit;
1763         sc_console = sc_get_stat(sc_get_softc(unit, SC_KERNEL_CONSOLE)->dev[0]);
1764         sc_consptr = cp;
1765 }
1766
1767 static void
1768 sc_cnterm(struct consdev *cp)
1769 {
1770         void *ts;
1771         int i;
1772
1773         /* we are not the kernel console any more, release everything */
1774
1775         if (sc_console_unit < 0)
1776                 return; /* shouldn't happen */
1777
1778 #if 0 /* XXX */
1779     sc_clear_screen(sc_console);
1780     sccnupdate(sc_console);
1781 #endif
1782
1783         if (sc_ktsw != NULL) {
1784                 for (i = 0; i <= mp_maxid; i++) {
1785                         ts = sc_kts[i];
1786                         sc_kts[i] = NULL;
1787                         (*sc_ktsw->te_term)(sc_console, &ts);
1788                         free(ts, M_DEVBUF);
1789                 }
1790                 sc_ktsw = NULL;
1791         }
1792         scterm(sc_console_unit, SC_KERNEL_CONSOLE);
1793         sc_console_unit = -1;
1794         sc_console = NULL;
1795 }
1796
1797 static void sccnclose(sc_softc_t *sc, struct sc_cnstate *sp);
1798 static int sc_cngetc_locked(struct sc_cnstate *sp);
1799 static void sccnkbdlock(sc_softc_t *sc, struct sc_cnstate *sp);
1800 static void sccnkbdunlock(sc_softc_t *sc, struct sc_cnstate *sp);
1801 static void sccnopen(sc_softc_t *sc, struct sc_cnstate *sp, int flags);
1802 static void sccnscrlock(sc_softc_t *sc, struct sc_cnstate *sp);
1803 static void sccnscrunlock(sc_softc_t *sc, struct sc_cnstate *sp);
1804
1805 static void
1806 sccnkbdlock(sc_softc_t *sc, struct sc_cnstate *sp)
1807 {
1808         /*
1809          * Locking method: hope for the best.
1810          * The keyboard is supposed to be Giant locked.  We can't handle that
1811          * in general.  The kdb_active case here is not safe, and we will
1812          * proceed without the lock in all cases.
1813          */
1814         sp->kbd_locked = !kdb_active && mtx_trylock(&Giant);
1815 }
1816
1817 static void
1818 sccnkbdunlock(sc_softc_t *sc, struct sc_cnstate *sp)
1819 {
1820         if (sp->kbd_locked)
1821                 mtx_unlock(&Giant);
1822         sp->kbd_locked = FALSE;
1823 }
1824
1825 static void
1826 sccnscrlock(sc_softc_t *sc, struct sc_cnstate *sp)
1827 {
1828         int retries;
1829
1830         /**
1831          * Locking method:
1832          * - if kdb_active and video_mtx is not owned by anyone, then lock
1833          *   by kdb remaining active
1834          * - if !kdb_active, try to acquire video_mtx without blocking or
1835          *   recursing; if we get it then it works normally.
1836          * Note that video_mtx is especially unusable if we already own it,
1837          * since then it is protecting something and syscons is not reentrant
1838          * enough to ignore the protection even in the kdb_active case.
1839          */
1840         if (kdb_active) {
1841                 sp->kdb_locked = sc->video_mtx.mtx_lock == MTX_UNOWNED ||
1842                     SCHEDULER_STOPPED();
1843                 sp->mtx_locked = FALSE;
1844         } else {
1845                 sp->kdb_locked = FALSE;
1846                 for (retries = 0; retries < 1000; retries++) {
1847                         sp->mtx_locked = mtx_trylock_spin_flags(
1848                                              &sc->video_mtx, MTX_QUIET) != 0;
1849                         if (SCHEDULER_STOPPED()) {
1850                                 sp->kdb_locked = TRUE;
1851                                 sp->mtx_locked = FALSE;
1852                                 break;
1853                         }
1854                         if (sp->mtx_locked)
1855                                 break;
1856                         DELAY(1);
1857                 }
1858         }
1859 }
1860
1861 static void
1862 sccnscrunlock(sc_softc_t *sc, struct sc_cnstate *sp)
1863 {
1864         if (sp->mtx_locked)
1865                 mtx_unlock_spin(&sc->video_mtx);
1866         sp->mtx_locked = sp->kdb_locked = FALSE;
1867 }
1868
1869 static void
1870 sccnopen(sc_softc_t *sc, struct sc_cnstate *sp, int flags)
1871 {
1872         int kbd_mode;
1873
1874         /* assert(sc_console_unit >= 0) */
1875
1876         sp->kbd_opened = FALSE;
1877         sp->scr_opened = FALSE;
1878         sp->kbd_locked = FALSE;
1879
1880         /* Opening the keyboard is optional. */
1881         if (!(flags & 1) || sc->kbd == NULL)
1882                 goto over_keyboard;
1883
1884         sccnkbdlock(sc, sp);
1885
1886         /*
1887          * Make sure the keyboard is accessible even when the kbd device
1888          * driver is disabled.
1889          */
1890         kbdd_enable(sc->kbd);
1891
1892         /* Switch the keyboard to console mode (K_XLATE, polled) on all scp's.
1893          */
1894         kbd_mode = K_XLATE;
1895         (void)kbdd_ioctl(sc->kbd, KDSKBMODE, (caddr_t)&kbd_mode);
1896         sc->kbd_open_level++;
1897         kbdd_poll(sc->kbd, TRUE);
1898
1899         sp->kbd_opened = TRUE;
1900 over_keyboard:;
1901
1902         /* The screen is opened iff locking it succeeds. */
1903         sccnscrlock(sc, sp);
1904         if (!sp->kdb_locked && !sp->mtx_locked)
1905                 return;
1906         sp->scr_opened = TRUE;
1907
1908         /* The screen switch is optional. */
1909         if (!(flags & 2))
1910                 return;
1911
1912         /* try to switch to the kernel console screen */
1913         if (!cold && sc->cur_scp->index != sc_console->index &&
1914             sc->cur_scp->smode.mode == VT_AUTO &&
1915             sc_console->smode.mode == VT_AUTO)
1916                 sc_switch_scr(sc, sc_console->index);
1917 }
1918
1919 static void
1920 sccnclose(sc_softc_t *sc, struct sc_cnstate *sp)
1921 {
1922         sp->scr_opened = FALSE;
1923         sccnscrunlock(sc, sp);
1924
1925         if (!sp->kbd_opened)
1926                 return;
1927
1928         /* Restore keyboard mode (for the current, possibly-changed scp). */
1929         kbdd_poll(sc->kbd, FALSE);
1930         if (--sc->kbd_open_level == 0)
1931                 (void)kbdd_ioctl(
1932                     sc->kbd, KDSKBMODE, (caddr_t)&sc->cur_scp->kbd_mode);
1933
1934         kbdd_disable(sc->kbd);
1935         sp->kbd_opened = FALSE;
1936         sccnkbdunlock(sc, sp);
1937 }
1938
1939 /*
1940  * Grabbing switches the screen and keyboard focus to sc_console and the
1941  * keyboard mode to (K_XLATE, polled).  Only switching to polled mode is
1942  * essential (for preventing the interrupt handler from eating input
1943  * between polls).  Focus is part of the UI, and the other switches are
1944  * work just was well when they are done on every entry and exit.
1945  *
1946  * Screen switches while grabbed are supported, and to maintain focus for
1947  * this ungrabbing and closing only restore the polling state and then
1948  * the keyboard mode if on the original screen.
1949  */
1950
1951 static void
1952 sc_cngrab(struct consdev *cp)
1953 {
1954         sc_softc_t *sc;
1955         int lev;
1956
1957         sc = sc_console->sc;
1958         lev = atomic_fetchadd_int(&sc->grab_level, 1);
1959         if (lev >= 0 && lev < 2) {
1960                 sccnopen(sc, &sc->grab_state[lev], 1 | 2);
1961                 sccnscrunlock(sc, &sc->grab_state[lev]);
1962                 sccnkbdunlock(sc, &sc->grab_state[lev]);
1963         }
1964 }
1965
1966 static void
1967 sc_cnungrab(struct consdev *cp)
1968 {
1969         sc_softc_t *sc;
1970         int lev;
1971
1972         sc = sc_console->sc;
1973         lev = atomic_load_acq_int(&sc->grab_level) - 1;
1974         if (lev >= 0 && lev < 2) {
1975                 sccnkbdlock(sc, &sc->grab_state[lev]);
1976                 sccnscrlock(sc, &sc->grab_state[lev]);
1977                 sccnclose(sc, &sc->grab_state[lev]);
1978         }
1979         atomic_add_int(&sc->grab_level, -1);
1980 }
1981
1982 static char sc_cnputc_log[0x1000];
1983 static u_int sc_cnputc_loghead;
1984 static u_int sc_cnputc_logtail;
1985
1986 static void
1987 sc_cnputc(struct consdev *cd, int c)
1988 {
1989         struct sc_cnstate st;
1990         u_char buf[1];
1991         scr_stat *scp = sc_console;
1992         void *oldts, *ts;
1993         struct sc_term_sw *oldtsw;
1994 #ifndef SC_NO_HISTORY
1995 #if 0
1996     struct tty *tp;
1997 #endif
1998 #endif /* !SC_NO_HISTORY */
1999         u_int head;
2000         int s;
2001
2002         /* assert(sc_console != NULL) */
2003
2004         sccnopen(scp->sc, &st, 0);
2005
2006         /*
2007          * Log the output.
2008          *
2009          * In the unlocked case, the logging is intentionally only
2010          * perfectly atomic for the indexes.
2011          */
2012         head = atomic_fetchadd_int(&sc_cnputc_loghead, 1);
2013         sc_cnputc_log[head % sizeof(sc_cnputc_log)] = c;
2014
2015         /*
2016          * If we couldn't open, do special reentrant output and return to defer
2017          * normal output.
2018          */
2019         if (!st.scr_opened) {
2020                 ec_putc(c);
2021                 return;
2022         }
2023
2024 #ifndef SC_NO_HISTORY
2025         if (scp == scp->sc->cur_scp && scp->status & SLKED) {
2026                 scp->status &= ~SLKED;
2027                 update_kbd_state(scp, scp->status, SLKED);
2028                 if (scp->status & BUFFER_SAVED) {
2029                         if (!sc_hist_restore(scp))
2030                                 sc_remove_cutmarking(scp);
2031                         scp->status &= ~BUFFER_SAVED;
2032                         scp->status |= CURSOR_ENABLED;
2033                         sc_draw_cursor_image(scp);
2034                 }
2035 #if 0
2036         /*
2037          * XXX: Now that TTY's have their own locks, we cannot process
2038          * any data after disabling scroll lock. cnputs already holds a
2039          * spinlock.
2040          */
2041         tp = SC_DEV(scp->sc, scp->index);
2042         /* XXX "tp" can be NULL */
2043         tty_lock(tp);
2044         if (tty_opened(tp))
2045             sctty_outwakeup(tp);
2046         tty_unlock(tp);
2047 #endif
2048         }
2049 #endif /* !SC_NO_HISTORY */
2050
2051         /* Play any output still in the log (our char may already be done). */
2052         while (sc_cnputc_logtail != atomic_load_acq_int(&sc_cnputc_loghead)) {
2053                 buf[0] =
2054                     sc_cnputc_log[sc_cnputc_logtail++ % sizeof(sc_cnputc_log)];
2055                 if (atomic_load_acq_int(&sc_cnputc_loghead) -
2056                         sc_cnputc_logtail >=
2057                     sizeof(sc_cnputc_log))
2058                         continue;
2059                 /* Console output has a per-CPU "input" state.  Switch for it.
2060                  */
2061                 ts = sc_kts[curcpu];
2062                 if (ts != NULL) {
2063                         oldtsw = scp->tsw;
2064                         oldts = scp->ts;
2065                         scp->tsw = sc_ktsw;
2066                         scp->ts = ts;
2067                         (*scp->tsw->te_sync)(scp);
2068                 } else {
2069                         /* Only 1 tsw early.  Switch only its attr. */
2070                         (*scp->tsw->te_default_attr)(
2071                             scp, sc_kattrtab[curcpu], SC_KERNEL_CONS_REV_ATTR);
2072                 }
2073                 sc_puts(scp, buf, 1);
2074                 if (ts != NULL) {
2075                         scp->tsw = oldtsw;
2076                         scp->ts = oldts;
2077                         (*scp->tsw->te_sync)(scp);
2078                 } else {
2079                         (*scp->tsw->te_default_attr)(
2080                             scp, SC_KERNEL_CONS_ATTR, SC_KERNEL_CONS_REV_ATTR);
2081                 }
2082         }
2083
2084         s = spltty(); /* block sckbdevent and scrn_timer */
2085         sccnupdate(scp);
2086         splx(s);
2087         sccnclose(scp->sc, &st);
2088 }
2089
2090 static int
2091 sc_cngetc(struct consdev *cd)
2092 {
2093         struct sc_cnstate st;
2094         int c, s;
2095
2096         /* assert(sc_console != NULL) */
2097         sccnopen(sc_console->sc, &st, 1);
2098         s = spltty(); /* block sckbdevent and scrn_timer while we poll */
2099         if (!st.kbd_opened) {
2100                 splx(s);
2101                 sccnclose(sc_console->sc, &st);
2102                 return -1; /* means no keyboard since we fudged the locking */
2103         }
2104         c = sc_cngetc_locked(&st);
2105         splx(s);
2106         sccnclose(sc_console->sc, &st);
2107         return c;
2108 }
2109
2110 static int
2111 sc_cngetc_locked(struct sc_cnstate *sp)
2112 {
2113         static struct fkeytab fkey;
2114         static int fkeycp;
2115         scr_stat *scp;
2116         const u_char *p;
2117         int c;
2118
2119         /*
2120          * Stop the screen saver and update the screen if necessary.
2121          * What if we have been running in the screen saver code... XXX
2122          */
2123         if (sp->scr_opened)
2124                 sc_touch_scrn_saver();
2125         scp = sc_console->sc->cur_scp; /* XXX */
2126         if (sp->scr_opened)
2127                 sccnupdate(scp);
2128
2129         if (fkeycp < fkey.len)
2130                 return fkey.str[fkeycp++];
2131
2132         c = scgetc(scp->sc, SCGETC_CN | SCGETC_NONBLOCK, sp);
2133
2134         switch (KEYFLAGS(c)) {
2135         case 0: /* normal char */
2136                 return KEYCHAR(c);
2137         case FKEY: /* function key */
2138                 p = (*scp->tsw->te_fkeystr)(scp, c);
2139                 if (p != NULL) {
2140                         fkey.len = strlen(p);
2141                         bcopy(p, fkey.str, fkey.len);
2142                         fkeycp = 1;
2143                         return fkey.str[0];
2144                 }
2145                 p = kbdd_get_fkeystr(
2146                     scp->sc->kbd, KEYCHAR(c), (size_t *)&fkeycp);
2147                 fkey.len = fkeycp;
2148                 if ((p != NULL) && (fkey.len > 0)) {
2149                         bcopy(p, fkey.str, fkey.len);
2150                         fkeycp = 1;
2151                         return fkey.str[0];
2152                 }
2153                 return c; /* XXX */
2154         case NOKEY:
2155         case ERRKEY:
2156         default:
2157                 return -1;
2158         }
2159         /* NOT REACHED */
2160 }
2161
2162 static void
2163 sccnupdate(scr_stat *scp)
2164 {
2165         /* this is a cut-down version of scrn_timer()... */
2166
2167         if (suspend_in_progress || scp->sc->font_loading_in_progress)
2168                 return;
2169
2170         if (kdb_active || panicstr || shutdown_in_progress) {
2171                 sc_touch_scrn_saver();
2172         } else if (scp != scp->sc->cur_scp) {
2173                 return;
2174         }
2175
2176         if (!run_scrn_saver)
2177                 scp->sc->flags &= ~SC_SCRN_IDLE;
2178 #ifdef DEV_SPLASH
2179         if ((saver_mode != CONS_LKM_SAVER) || !(scp->sc->flags & SC_SCRN_IDLE))
2180                 if (scp->sc->flags & SC_SCRN_BLANKED)
2181                         stop_scrn_saver(scp->sc, current_saver);
2182 #endif
2183
2184         if (scp != scp->sc->cur_scp || scp->sc->blink_in_progress ||
2185             scp->sc->switch_in_progress)
2186                 return;
2187         /*
2188          * FIXME: unlike scrn_timer(), we call scrn_update() from here even
2189          * when write_in_progress is non-zero.  XXX
2190          */
2191
2192         if (!ISGRAPHSC(scp) && !(scp->sc->flags & SC_SCRN_BLANKED))
2193                 scrn_update(scp, TRUE);
2194 }
2195
2196 static void
2197 scrn_timer(void *arg)
2198 {
2199         static time_t kbd_time_stamp = 0;
2200         sc_softc_t *sc;
2201         scr_stat *scp;
2202         int again, rate;
2203
2204         again = (arg != NULL);
2205         if (arg != NULL)
2206                 sc = (sc_softc_t *)arg;
2207         else if (sc_console != NULL)
2208                 sc = sc_console->sc;
2209         else
2210                 return;
2211
2212         /* find the vty to update */
2213         scp = sc->cur_scp;
2214
2215         /* don't do anything when we are performing some I/O operations */
2216         if (suspend_in_progress || sc->font_loading_in_progress)
2217                 goto done;
2218
2219         if ((sc->kbd == NULL) && (sc->config & SC_AUTODETECT_KBD)) {
2220                 /* try to allocate a keyboard automatically */
2221                 if (kbd_time_stamp != time_uptime) {
2222                         kbd_time_stamp = time_uptime;
2223                         sc->keyboard = sc_allocate_keyboard(sc, -1);
2224                         if (sc->keyboard >= 0) {
2225                                 sc->kbd = kbd_get_keyboard(sc->keyboard);
2226                                 (void)kbdd_ioctl(sc->kbd, KDSKBMODE,
2227                                     (caddr_t)&sc->cur_scp->kbd_mode);
2228                                 update_kbd_state(sc->cur_scp,
2229                                     sc->cur_scp->status, LOCK_MASK);
2230                         }
2231                 }
2232         }
2233
2234         /* should we stop the screen saver? */
2235         if (kdb_active || panicstr || shutdown_in_progress)
2236                 sc_touch_scrn_saver();
2237         if (run_scrn_saver) {
2238                 if (time_uptime > sc->scrn_time_stamp + scrn_blank_time)
2239                         sc->flags |= SC_SCRN_IDLE;
2240                 else
2241                         sc->flags &= ~SC_SCRN_IDLE;
2242         } else {
2243                 sc->scrn_time_stamp = time_uptime;
2244                 sc->flags &= ~SC_SCRN_IDLE;
2245                 if (scrn_blank_time > 0)
2246                         run_scrn_saver = TRUE;
2247         }
2248 #ifdef DEV_SPLASH
2249         if ((saver_mode != CONS_LKM_SAVER) || !(sc->flags & SC_SCRN_IDLE))
2250                 if (sc->flags & SC_SCRN_BLANKED)
2251                         stop_scrn_saver(sc, current_saver);
2252 #endif
2253
2254         /* should we just return ? */
2255         if (sc->blink_in_progress || sc->switch_in_progress ||
2256             sc->write_in_progress)
2257                 goto done;
2258
2259         /* Update the screen */
2260         scp = sc->cur_scp; /* cur_scp may have changed... */
2261         if (!ISGRAPHSC(scp) && !(sc->flags & SC_SCRN_BLANKED))
2262                 scrn_update(scp, TRUE);
2263
2264 #ifdef DEV_SPLASH
2265         /* should we activate the screen saver? */
2266         if ((saver_mode == CONS_LKM_SAVER) && (sc->flags & SC_SCRN_IDLE))
2267                 if (!ISGRAPHSC(scp) || (sc->flags & SC_SCRN_BLANKED))
2268                         (*current_saver)(sc, TRUE);
2269 #endif
2270
2271 done:
2272         if (again) {
2273                 /*
2274                  * Use reduced "refresh" rate if we are in graphics and that is
2275                  * not a graphical screen saver.  In such case we just have
2276                  * nothing to do.
2277                  */
2278                 if (ISGRAPHSC(scp) && !(sc->flags & SC_SCRN_BLANKED))
2279                         rate = 2;
2280                 else
2281                         rate = 30;
2282                 callout_reset_sbt(
2283                     &sc->ctimeout, SBT_1S / rate, 0, scrn_timer, sc, C_PREL(1));
2284         }
2285 }
2286
2287 static int
2288 and_region(int *s1, int *e1, int s2, int e2)
2289 {
2290         if (*e1 < s2 || e2 < *s1)
2291                 return FALSE;
2292         *s1 = imax(*s1, s2);
2293         *e1 = imin(*e1, e2);
2294         return TRUE;
2295 }
2296
2297 static void
2298 scrn_update(scr_stat *scp, int show_cursor)
2299 {
2300         int start;
2301         int end;
2302         int s;
2303         int e;
2304
2305         /* assert(scp == scp->sc->cur_scp) */
2306
2307         SC_VIDEO_LOCK(scp->sc);
2308
2309 #ifndef SC_NO_CUTPASTE
2310         /* remove the previous mouse pointer image if necessary */
2311         if (scp->status & MOUSE_VISIBLE) {
2312                 s = scp->mouse_pos;
2313                 e = scp->mouse_pos + scp->xsize + 1;
2314                 if ((scp->status & (MOUSE_MOVED | MOUSE_HIDDEN)) ||
2315                     and_region(&s, &e, scp->start, scp->end) ||
2316                     ((scp->status & CURSOR_ENABLED) &&
2317                         (scp->cursor_pos != scp->cursor_oldpos) &&
2318                         (and_region(&s, &e, scp->cursor_pos, scp->cursor_pos) ||
2319                             and_region(&s, &e, scp->cursor_oldpos,
2320                                 scp->cursor_oldpos)))) {
2321                         sc_remove_mouse_image(scp);
2322                         if (scp->end >= scp->xsize * scp->ysize)
2323                                 scp->end = scp->xsize * scp->ysize - 1;
2324                 }
2325         }
2326 #endif /* !SC_NO_CUTPASTE */
2327
2328 #if 1
2329         /* debug: XXX */
2330         if (scp->end >= scp->xsize * scp->ysize) {
2331                 printf("scrn_update(): scp->end %d > size_of_screen!!\n",
2332                     scp->end);
2333                 scp->end = scp->xsize * scp->ysize - 1;
2334         }
2335         if (scp->start < 0) {
2336                 printf("scrn_update(): scp->start %d < 0\n", scp->start);
2337                 scp->start = 0;
2338         }
2339 #endif
2340
2341         /* update screen image */
2342         if (scp->start <= scp->end) {
2343                 if (scp->mouse_cut_end >= 0) {
2344                         /* there is a marked region for cut & paste */
2345                         if (scp->mouse_cut_start <= scp->mouse_cut_end) {
2346                                 start = scp->mouse_cut_start;
2347                                 end = scp->mouse_cut_end;
2348                         } else {
2349                                 start = scp->mouse_cut_end;
2350                                 end = scp->mouse_cut_start - 1;
2351                         }
2352                         s = start;
2353                         e = end;
2354                         /* does the cut-mark region overlap with the update
2355                          * region? */
2356                         if (and_region(&s, &e, scp->start, scp->end)) {
2357                                 (*scp->rndr->draw)(scp, s, e - s + 1, TRUE);
2358                                 s = 0;
2359                                 e = start - 1;
2360                                 if (and_region(&s, &e, scp->start, scp->end))
2361                                         (*scp->rndr->draw)(
2362                                             scp, s, e - s + 1, FALSE);
2363                                 s = end + 1;
2364                                 e = scp->xsize * scp->ysize - 1;
2365                                 if (and_region(&s, &e, scp->start, scp->end))
2366                                         (*scp->rndr->draw)(
2367                                             scp, s, e - s + 1, FALSE);
2368                         } else {
2369                                 (*scp->rndr->draw)(scp, scp->start,
2370                                     scp->end - scp->start + 1, FALSE);
2371                         }
2372                 } else {
2373                         (*scp->rndr->draw)(
2374                             scp, scp->start, scp->end - scp->start + 1, FALSE);
2375                 }
2376         }
2377
2378         /* we are not to show the cursor and the mouse pointer... */
2379         if (!show_cursor) {
2380                 scp->end = 0;
2381                 scp->start = scp->xsize * scp->ysize - 1;
2382                 SC_VIDEO_UNLOCK(scp->sc);
2383                 return;
2384         }
2385
2386         /* update cursor image */
2387         if (scp->status & CURSOR_ENABLED) {
2388                 s = scp->start;
2389                 e = scp->end;
2390                 /* did cursor move since last time ? */
2391                 if (scp->cursor_pos != scp->cursor_oldpos) {
2392                         /* do we need to remove old cursor image ? */
2393                         if (!and_region(
2394                                 &s, &e, scp->cursor_oldpos, scp->cursor_oldpos))
2395                                 sc_remove_cursor_image(scp);
2396                         sc_draw_cursor_image(scp);
2397                 } else {
2398                         if (and_region(
2399                                 &s, &e, scp->cursor_pos, scp->cursor_pos))
2400                                 /* cursor didn't move, but has been overwritten
2401                                  */
2402                                 sc_draw_cursor_image(scp);
2403                         else if (scp->curs_attr.flags & CONS_BLINK_CURSOR)
2404                                 /* if it's a blinking cursor, update it */
2405                                 (*scp->rndr->blink_cursor)(scp, scp->cursor_pos,
2406                                     sc_inside_cutmark(scp, scp->cursor_pos));
2407                 }
2408         }
2409
2410 #ifndef SC_NO_CUTPASTE
2411         /* update "pseudo" mouse pointer image */
2412         if (scp->sc->flags & SC_MOUSE_ENABLED) {
2413                 if (!(scp->status & (MOUSE_VISIBLE | MOUSE_HIDDEN))) {
2414                         scp->status &= ~MOUSE_MOVED;
2415                         sc_draw_mouse_image(scp);
2416                 }
2417         }
2418 #endif /* SC_NO_CUTPASTE */
2419
2420         scp->end = 0;
2421         scp->start = scp->xsize * scp->ysize - 1;
2422
2423         SC_VIDEO_UNLOCK(scp->sc);
2424 }
2425
2426 #ifdef DEV_SPLASH
2427 static int
2428 scsplash_callback(int event, void *arg)
2429 {
2430         sc_softc_t *sc;
2431         int error;
2432
2433         sc = (sc_softc_t *)arg;
2434
2435         switch (event) {
2436         case SPLASH_INIT:
2437                 if (add_scrn_saver(scsplash_saver) == 0) {
2438                         sc->flags &= ~SC_SAVER_FAILED;
2439                         run_scrn_saver = TRUE;
2440                         if (cold && !(boothowto & RB_VERBOSE)) {
2441                                 scsplash_stick(TRUE);
2442                                 (*current_saver)(sc, TRUE);
2443                         }
2444                 }
2445                 return 0;
2446
2447         case SPLASH_TERM:
2448                 if (current_saver == scsplash_saver) {
2449                         scsplash_stick(FALSE);
2450                         error = remove_scrn_saver(scsplash_saver);
2451                         if (error)
2452                                 return error;
2453                 }
2454                 return 0;
2455
2456         default:
2457                 return EINVAL;
2458         }
2459 }
2460
2461 static void
2462 scsplash_saver(sc_softc_t *sc, int show)
2463 {
2464         static int busy = FALSE;
2465         scr_stat *scp;
2466
2467         if (busy)
2468                 return;
2469         busy = TRUE;
2470
2471         scp = sc->cur_scp;
2472         if (show) {
2473                 if (!(sc->flags & SC_SAVER_FAILED)) {
2474                         if (!(sc->flags & SC_SCRN_BLANKED))
2475                                 set_scrn_saver_mode(scp, -1, NULL, 0);
2476                         switch (splash(sc->adp, TRUE)) {
2477                         case 0: /* succeeded */
2478                                 break;
2479                         case EAGAIN: /* try later */
2480                                 restore_scrn_saver_mode(scp, FALSE);
2481                                 sc_touch_scrn_saver(); /* XXX */
2482                                 break;
2483                         default:
2484                                 sc->flags |= SC_SAVER_FAILED;
2485                                 scsplash_stick(FALSE);
2486                                 restore_scrn_saver_mode(scp, TRUE);
2487                                 printf(
2488                                     "scsplash_saver(): failed to put up the image\n");
2489                                 break;
2490                         }
2491                 }
2492         } else if (!sticky_splash) {
2493                 if ((sc->flags & SC_SCRN_BLANKED) &&
2494                     (splash(sc->adp, FALSE) == 0))
2495                         restore_scrn_saver_mode(scp, TRUE);
2496         }
2497         busy = FALSE;
2498 }
2499
2500 static int
2501 add_scrn_saver(void (*this_saver)(sc_softc_t *, int))
2502 {
2503 #if 0
2504     int error;
2505
2506     if (current_saver != none_saver) {
2507         error = remove_scrn_saver(current_saver);
2508         if (error)
2509             return error;
2510     }
2511 #endif
2512         if (current_saver != none_saver)
2513                 return EBUSY;
2514
2515         run_scrn_saver = FALSE;
2516         saver_mode = CONS_LKM_SAVER;
2517         current_saver = this_saver;
2518         return 0;
2519 }
2520
2521 static int
2522 remove_scrn_saver(void (*this_saver)(sc_softc_t *, int))
2523 {
2524         if (current_saver != this_saver)
2525                 return EINVAL;
2526
2527 #if 0
2528     /*
2529      * In order to prevent `current_saver' from being called by
2530      * the timeout routine `scrn_timer()' while we manipulate 
2531      * the saver list, we shall set `current_saver' to `none_saver' 
2532      * before stopping the current saver, rather than blocking by `splXX()'.
2533      */
2534     current_saver = none_saver;
2535     if (scrn_blanked)
2536         stop_scrn_saver(this_saver);
2537 #endif
2538
2539         /* unblank all blanked screens */
2540         wait_scrn_saver_stop(NULL);
2541         if (scrn_blanked)
2542                 return EBUSY;
2543
2544         current_saver = none_saver;
2545         return 0;
2546 }
2547
2548 static int
2549 set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border)
2550 {
2551         int s;
2552
2553         /* assert(scp == scp->sc->cur_scp) */
2554         s = spltty();
2555         if (!ISGRAPHSC(scp))
2556                 sc_remove_cursor_image(scp);
2557         scp->splash_save_mode = scp->mode;
2558         scp->splash_save_status = scp->status & (GRAPHICS_MODE | PIXEL_MODE);
2559         scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
2560         scp->status |= (UNKNOWN_MODE | SAVER_RUNNING);
2561         scp->sc->flags |= SC_SCRN_BLANKED;
2562         ++scrn_blanked;
2563         splx(s);
2564         if (mode < 0)
2565                 return 0;
2566         scp->mode = mode;
2567         if (set_mode(scp) == 0) {
2568                 if (scp->sc->adp->va_info.vi_flags & V_INFO_GRAPHICS)
2569                         scp->status |= GRAPHICS_MODE;
2570 #ifndef SC_NO_PALETTE_LOADING
2571                 if (pal != NULL)
2572                         vidd_load_palette(scp->sc->adp, pal);
2573 #endif
2574                 sc_set_border(scp, border);
2575                 return 0;
2576         } else {
2577                 s = spltty();
2578                 scp->mode = scp->splash_save_mode;
2579                 scp->status &= ~(UNKNOWN_MODE | SAVER_RUNNING);
2580                 scp->status |= scp->splash_save_status;
2581                 splx(s);
2582                 return 1;
2583         }
2584 }
2585
2586 static int
2587 restore_scrn_saver_mode(scr_stat *scp, int changemode)
2588 {
2589         int mode;
2590         int status;
2591         int s;
2592
2593         /* assert(scp == scp->sc->cur_scp) */
2594         s = spltty();
2595         mode = scp->mode;
2596         status = scp->status;
2597         scp->mode = scp->splash_save_mode;
2598         scp->status &= ~(UNKNOWN_MODE | SAVER_RUNNING);
2599         scp->status |= scp->splash_save_status;
2600         scp->sc->flags &= ~SC_SCRN_BLANKED;
2601         if (!changemode) {
2602                 if (!ISGRAPHSC(scp))
2603                         sc_draw_cursor_image(scp);
2604                 --scrn_blanked;
2605                 splx(s);
2606                 return 0;
2607         }
2608         if (set_mode(scp) == 0) {
2609 #ifndef SC_NO_PALETTE_LOADING
2610 #ifdef SC_PIXEL_MODE
2611                 if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT)
2612                         vidd_load_palette(scp->sc->adp, scp->sc->palette2);
2613                 else
2614 #endif
2615                         vidd_load_palette(scp->sc->adp, scp->sc->palette);
2616 #endif
2617                 --scrn_blanked;
2618                 splx(s);
2619                 return 0;
2620         } else {
2621                 scp->mode = mode;
2622                 scp->status = status;
2623                 splx(s);
2624                 return 1;
2625         }
2626 }
2627
2628 static void
2629 stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int))
2630 {
2631         (*saver)(sc, FALSE);
2632         run_scrn_saver = FALSE;
2633         /* the screen saver may have chosen not to stop after all... */
2634         if (sc->flags & SC_SCRN_BLANKED)
2635                 return;
2636
2637         mark_all(sc->cur_scp);
2638         if (sc->delayed_next_scr)
2639                 sc_switch_scr(sc, sc->delayed_next_scr - 1);
2640         if (!kdb_active)
2641                 wakeup(&scrn_blanked);
2642 }
2643
2644 static int
2645 wait_scrn_saver_stop(sc_softc_t *sc)
2646 {
2647         int error = 0;
2648
2649         while (scrn_blanked > 0) {
2650                 run_scrn_saver = FALSE;
2651                 if (sc && !(sc->flags & SC_SCRN_BLANKED)) {
2652                         error = 0;
2653                         break;
2654                 }
2655                 error = tsleep(&scrn_blanked, PZERO | PCATCH, "scrsav", 0);
2656                 if ((error != 0) && (error != ERESTART))
2657                         break;
2658         }
2659         run_scrn_saver = FALSE;
2660         return error;
2661 }
2662 #endif /* DEV_SPLASH */
2663
2664 void
2665 sc_touch_scrn_saver(void)
2666 {
2667         scsplash_stick(FALSE);
2668         run_scrn_saver = FALSE;
2669 }
2670
2671 int
2672 sc_switch_scr(sc_softc_t *sc, u_int next_scr)
2673 {
2674         scr_stat *cur_scp;
2675         struct tty *tp;
2676         struct proc *p;
2677         int s;
2678
2679         DPRINTF(5, ("sc0: sc_switch_scr() %d ", next_scr + 1));
2680
2681         if (sc->cur_scp == NULL)
2682                 return (0);
2683
2684         /* prevent switch if previously requested */
2685         if (sc->flags & SC_SCRN_VTYLOCK) {
2686                 sc_bell(sc->cur_scp, sc->cur_scp->bell_pitch,
2687                     sc->cur_scp->bell_duration);
2688                 return EPERM;
2689         }
2690
2691         /* delay switch if the screen is blanked or being updated */
2692         if ((sc->flags & SC_SCRN_BLANKED) || sc->write_in_progress ||
2693             sc->blink_in_progress) {
2694                 sc->delayed_next_scr = next_scr + 1;
2695                 sc_touch_scrn_saver();
2696                 DPRINTF(5, ("switch delayed\n"));
2697                 return 0;
2698         }
2699         sc->delayed_next_scr = 0;
2700
2701         s = spltty();
2702         cur_scp = sc->cur_scp;
2703
2704         /* we are in the middle of the vty switching process... */
2705         if (sc->switch_in_progress && (cur_scp->smode.mode == VT_PROCESS) &&
2706             cur_scp->proc) {
2707                 p = pfind(cur_scp->pid);
2708                 if (cur_scp->proc != p) {
2709                         if (p)
2710                                 PROC_UNLOCK(p);
2711                         /*
2712                          * The controlling process has died!!.  Do some clean
2713                          * up. NOTE:`cur_scp->proc' and `cur_scp->smode.mode'
2714                          * are not reset here yet; they will be cleared later.
2715                          */
2716                         DPRINTF(5,
2717                             ("cur_scp controlling process %d died, ",
2718                                 cur_scp->pid));
2719                         if (cur_scp->status & SWITCH_WAIT_REL) {
2720                                 /*
2721                                  * Force the previous switch to finish, but
2722                                  * return now with error.
2723                                  */
2724                                 DPRINTF(5, ("reset WAIT_REL, "));
2725                                 finish_vt_rel(cur_scp, TRUE, &s);
2726                                 splx(s);
2727                                 DPRINTF(5, ("finishing previous switch\n"));
2728                                 return EINVAL;
2729                         } else if (cur_scp->status & SWITCH_WAIT_ACQ) {
2730                                 /* let's assume screen switch has been
2731                                  * completed. */
2732                                 DPRINTF(5, ("reset WAIT_ACQ, "));
2733                                 finish_vt_acq(cur_scp);
2734                         } else {
2735                                 /*
2736                                  * We are in between screen release and
2737                                  * acquisition, and reached here via scgetc() or
2738                                  * scrn_timer() which has interrupted
2739                                  * exchange_scr(). Don't do anything stupid.
2740                                  */
2741                                 DPRINTF(5, ("waiting nothing, "));
2742                         }
2743                 } else {
2744                         if (p)
2745                                 PROC_UNLOCK(p);
2746                         /*
2747                          * The controlling process is alive, but not
2748                          * responding... It is either buggy or it may be just
2749                          * taking time. The following code is a gross kludge to
2750                          * cope with this problem for which there is no clean
2751                          * solution. XXX
2752                          */
2753                         if (cur_scp->status & SWITCH_WAIT_REL) {
2754                                 switch (sc->switch_in_progress++) {
2755                                 case 1:
2756                                         break;
2757                                 case 2:
2758                                         DPRINTF(5, ("sending relsig again, "));
2759                                         signal_vt_rel(cur_scp);
2760                                         break;
2761                                 case 3:
2762                                         break;
2763                                 case 4:
2764                                 default:
2765                                         /*
2766                                          * Act as if the controlling program
2767                                          * returned VT_FALSE.
2768                                          */
2769                                         DPRINTF(5, ("force reset WAIT_REL, "));
2770                                         finish_vt_rel(cur_scp, FALSE, &s);
2771                                         splx(s);
2772                                         DPRINTF(5,
2773                                             ("act as if VT_FALSE was seen\n"));
2774                                         return EINVAL;
2775                                 }
2776                         } else if (cur_scp->status & SWITCH_WAIT_ACQ) {
2777                                 switch (sc->switch_in_progress++) {
2778                                 case 1:
2779                                         break;
2780                                 case 2:
2781                                         DPRINTF(5, ("sending acqsig again, "));
2782                                         signal_vt_acq(cur_scp);
2783                                         break;
2784                                 case 3:
2785                                         break;
2786                                 case 4:
2787                                 default:
2788                                         /* clear the flag and finish the
2789                                          * previous switch */
2790                                         DPRINTF(5, ("force reset WAIT_ACQ, "));
2791                                         finish_vt_acq(cur_scp);
2792                                         break;
2793                                 }
2794                         }
2795                 }
2796         }
2797
2798         /*
2799          * Return error if an invalid argument is given, or vty switch
2800          * is still in progress.
2801          */
2802         if ((next_scr < sc->first_vty) ||
2803             (next_scr >= sc->first_vty + sc->vtys) || sc->switch_in_progress) {
2804                 splx(s);
2805                 sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION);
2806                 DPRINTF(5, ("error 1\n"));
2807                 return EINVAL;
2808         }
2809
2810         /*
2811          * Don't allow switching away from the graphics mode vty
2812          * if the switch mode is VT_AUTO, unless the next vty is the same
2813          * as the current or the current vty has been closed (but showing).
2814          */
2815         tp = SC_DEV(sc, cur_scp->index);
2816         if ((cur_scp->index != next_scr) && tty_opened_ns(tp) &&
2817             (cur_scp->smode.mode == VT_AUTO) && ISGRAPHSC(cur_scp)) {
2818                 splx(s);
2819                 sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION);
2820                 DPRINTF(5, ("error, graphics mode\n"));
2821                 return EINVAL;
2822         }
2823
2824         /*
2825          * Is the wanted vty open? Don't allow switching to a closed vty.
2826          * If we are in DDB, don't switch to a vty in the VT_PROCESS mode.
2827          * Note that we always allow the user to switch to the kernel
2828          * console even if it is closed.
2829          */
2830         if ((sc_console == NULL) || (next_scr != sc_console->index)) {
2831                 tp = SC_DEV(sc, next_scr);
2832                 if (!tty_opened_ns(tp)) {
2833                         splx(s);
2834                         sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION);
2835                         DPRINTF(5, ("error 2, requested vty isn't open!\n"));
2836                         return EINVAL;
2837                 }
2838                 if (kdb_active && SC_STAT(tp)->smode.mode == VT_PROCESS) {
2839                         splx(s);
2840                         DPRINTF(5,
2841                             ("error 3, requested vty is in the VT_PROCESS mode\n"));
2842                         return EINVAL;
2843                 }
2844         }
2845
2846         /* this is the start of vty switching process... */
2847         ++sc->switch_in_progress;
2848         sc->old_scp = cur_scp;
2849         sc->new_scp = sc_get_stat(SC_DEV(sc, next_scr));
2850         if (sc->new_scp == sc->old_scp) {
2851                 sc->switch_in_progress = 0;
2852                 /*
2853                  * XXX wakeup() locks the scheduler lock which will hang if
2854                  * the lock is in an in-between state, e.g., when we stop at
2855                  * a breakpoint at fork_exit.  It has always been wrong to call
2856                  * wakeup() when the debugger is active.  In RELENG_4, wakeup()
2857                  * is supposed to be locked by splhigh(), but the debugger may
2858                  * be invoked at splhigh().
2859                  */
2860                 if (!kdb_active)
2861                         wakeup(VTY_WCHAN(sc, next_scr));
2862                 splx(s);
2863                 DPRINTF(5, ("switch done (new == old)\n"));
2864                 return 0;
2865         }
2866
2867         /* has controlling process died? */
2868         vt_proc_alive(sc->old_scp);
2869         vt_proc_alive(sc->new_scp);
2870
2871         /* wait for the controlling process to release the screen, if necessary
2872          */
2873         if (signal_vt_rel(sc->old_scp)) {
2874                 splx(s);
2875                 return 0;
2876         }
2877
2878         /* go set up the new vty screen */
2879         splx(s);
2880         exchange_scr(sc);
2881         s = spltty();
2882
2883         /* wake up processes waiting for this vty */
2884         if (!kdb_active)
2885                 wakeup(VTY_WCHAN(sc, next_scr));
2886
2887         /* wait for the controlling process to acknowledge, if necessary */
2888         if (signal_vt_acq(sc->cur_scp)) {
2889                 splx(s);
2890                 return 0;
2891         }
2892
2893         sc->switch_in_progress = 0;
2894         if (sc->unit == sc_console_unit)
2895                 cnavailable(sc_consptr, TRUE);
2896         splx(s);
2897         DPRINTF(5, ("switch done\n"));
2898
2899         return 0;
2900 }
2901
2902 static int
2903 do_switch_scr(sc_softc_t *sc, int s)
2904 {
2905         vt_proc_alive(sc->new_scp);
2906
2907         splx(s);
2908         exchange_scr(sc);
2909         s = spltty();
2910         /* sc->cur_scp == sc->new_scp */
2911         wakeup(VTY_WCHAN(sc, sc->cur_scp->index));
2912
2913         /* wait for the controlling process to acknowledge, if necessary */
2914         if (!signal_vt_acq(sc->cur_scp)) {
2915                 sc->switch_in_progress = 0;
2916                 if (sc->unit == sc_console_unit)
2917                         cnavailable(sc_consptr, TRUE);
2918         }
2919
2920         return s;
2921 }
2922
2923 static int
2924 vt_proc_alive(scr_stat *scp)
2925 {
2926         struct proc *p;
2927
2928         if (scp->proc) {
2929                 if ((p = pfind(scp->pid)) != NULL)
2930                         PROC_UNLOCK(p);
2931                 if (scp->proc == p)
2932                         return TRUE;
2933                 scp->proc = NULL;
2934                 scp->smode.mode = VT_AUTO;
2935                 DPRINTF(5, ("vt controlling process %d died\n", scp->pid));
2936         }
2937         return FALSE;
2938 }
2939
2940 static int
2941 signal_vt_rel(scr_stat *scp)
2942 {
2943         if (scp->smode.mode != VT_PROCESS)
2944                 return FALSE;
2945         scp->status |= SWITCH_WAIT_REL;
2946         PROC_LOCK(scp->proc);
2947         kern_psignal(scp->proc, scp->smode.relsig);
2948         PROC_UNLOCK(scp->proc);
2949         DPRINTF(5, ("sending relsig to %d\n", scp->pid));
2950         return TRUE;
2951 }
2952
2953 static int
2954 signal_vt_acq(scr_stat *scp)
2955 {
2956         if (scp->smode.mode != VT_PROCESS)
2957                 return FALSE;
2958         if (scp->sc->unit == sc_console_unit)
2959                 cnavailable(sc_consptr, FALSE);
2960         scp->status |= SWITCH_WAIT_ACQ;
2961         PROC_LOCK(scp->proc);
2962         kern_psignal(scp->proc, scp->smode.acqsig);
2963         PROC_UNLOCK(scp->proc);
2964         DPRINTF(5, ("sending acqsig to %d\n", scp->pid));
2965         return TRUE;
2966 }
2967
2968 static int
2969 finish_vt_rel(scr_stat *scp, int release, int *s)
2970 {
2971         if (scp == scp->sc->old_scp && scp->status & SWITCH_WAIT_REL) {
2972                 scp->status &= ~SWITCH_WAIT_REL;
2973                 if (release)
2974                         *s = do_switch_scr(scp->sc, *s);
2975                 else
2976                         scp->sc->switch_in_progress = 0;
2977                 return 0;
2978         }
2979         return EINVAL;
2980 }
2981
2982 static int
2983 finish_vt_acq(scr_stat *scp)
2984 {
2985         if (scp == scp->sc->new_scp && scp->status & SWITCH_WAIT_ACQ) {
2986                 scp->status &= ~SWITCH_WAIT_ACQ;
2987                 scp->sc->switch_in_progress = 0;
2988                 return 0;
2989         }
2990         return EINVAL;
2991 }
2992
2993 static void
2994 exchange_scr(sc_softc_t *sc)
2995 {
2996         scr_stat *scp;
2997
2998         /* save the current state of video and keyboard */
2999         sc_move_cursor(sc->old_scp, sc->old_scp->xpos, sc->old_scp->ypos);
3000         if (!ISGRAPHSC(sc->old_scp))
3001                 sc_remove_cursor_image(sc->old_scp);
3002         if (sc->old_scp->kbd_mode == K_XLATE)
3003                 save_kbd_state(sc->old_scp);
3004
3005         /* set up the video for the new screen */
3006         scp = sc->cur_scp = sc->new_scp;
3007         if (sc->old_scp->mode != scp->mode || ISUNKNOWNSC(sc->old_scp))
3008                 set_mode(scp);
3009 #ifndef __sparc64__
3010         else
3011                 sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
3012                     (void *)sc->adp->va_window, FALSE);
3013 #endif
3014         scp->status |= MOUSE_HIDDEN;
3015         sc_move_cursor(scp, scp->xpos, scp->ypos);
3016         if (!ISGRAPHSC(scp))
3017                 sc_set_cursor_image(scp);
3018 #ifndef SC_NO_PALETTE_LOADING
3019         if (ISGRAPHSC(sc->old_scp)) {
3020 #ifdef SC_PIXEL_MODE
3021                 if (sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT)
3022                         vidd_load_palette(sc->adp, sc->palette2);
3023                 else
3024 #endif
3025                         vidd_load_palette(sc->adp, sc->palette);
3026         }
3027 #endif
3028         sc_set_border(scp, scp->border);
3029
3030         /* set up the keyboard for the new screen */
3031         if (sc->kbd_open_level == 0 && sc->old_scp->kbd_mode != scp->kbd_mode)
3032                 (void)kbdd_ioctl(sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
3033         update_kbd_state(scp, scp->status, LOCK_MASK);
3034
3035         mark_all(scp);
3036 }
3037
3038 static void
3039 sc_puts(scr_stat *scp, u_char *buf, int len)
3040 {
3041 #ifdef DEV_SPLASH
3042         /* make screensaver happy */
3043         if (!sticky_splash && scp == scp->sc->cur_scp && !sc_saver_keyb_only)
3044                 run_scrn_saver = FALSE;
3045 #endif
3046
3047         if (scp->tsw)
3048                 (*scp->tsw->te_puts)(scp, buf, len);
3049         if (scp->sc->delayed_next_scr)
3050                 sc_switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
3051 }
3052
3053 void
3054 sc_draw_cursor_image(scr_stat *scp)
3055 {
3056         /* assert(scp == scp->sc->cur_scp); */
3057         SC_VIDEO_LOCK(scp->sc);
3058         (*scp->rndr->draw_cursor)(scp, scp->cursor_pos,
3059             scp->curs_attr.flags & CONS_BLINK_CURSOR, TRUE,
3060             sc_inside_cutmark(scp, scp->cursor_pos));
3061         scp->cursor_oldpos = scp->cursor_pos;
3062         SC_VIDEO_UNLOCK(scp->sc);
3063 }
3064
3065 void
3066 sc_remove_cursor_image(scr_stat *scp)
3067 {
3068         /* assert(scp == scp->sc->cur_scp); */
3069         SC_VIDEO_LOCK(scp->sc);
3070         (*scp->rndr->draw_cursor)(scp, scp->cursor_oldpos,
3071             scp->curs_attr.flags & CONS_BLINK_CURSOR, FALSE,
3072             sc_inside_cutmark(scp, scp->cursor_oldpos));
3073         SC_VIDEO_UNLOCK(scp->sc);
3074 }
3075
3076 static void
3077 update_cursor_image(scr_stat *scp)
3078 {
3079         /* assert(scp == scp->sc->cur_scp); */
3080         sc_remove_cursor_image(scp);
3081         sc_set_cursor_image(scp);
3082         sc_draw_cursor_image(scp);
3083 }
3084
3085 void
3086 sc_set_cursor_image(scr_stat *scp)
3087 {
3088         scp->curs_attr = scp->base_curs_attr;
3089         if (scp->curs_attr.flags & CONS_HIDDEN_CURSOR) {
3090                 /* hidden cursor is internally represented as zero-height
3091                  * underline */
3092                 scp->curs_attr.flags = CONS_CHAR_CURSOR;
3093                 scp->curs_attr.base = scp->curs_attr.height = 0;
3094         } else if (scp->curs_attr.flags & CONS_CHAR_CURSOR) {
3095                 scp->curs_attr.base =
3096                     imin(scp->base_curs_attr.base, scp->font_size - 1);
3097                 scp->curs_attr.height = imin(scp->base_curs_attr.height,
3098                     scp->font_size - scp->curs_attr.base);
3099         } else { /* block cursor */
3100                 scp->curs_attr.base = 0;
3101                 scp->curs_attr.height = scp->font_size;
3102         }
3103
3104         /* assert(scp == scp->sc->cur_scp); */
3105         SC_VIDEO_LOCK(scp->sc);
3106         (*scp->rndr->set_cursor)(scp, scp->curs_attr.base,
3107             scp->curs_attr.height, scp->curs_attr.flags & CONS_BLINK_CURSOR);
3108         SC_VIDEO_UNLOCK(scp->sc);
3109 }
3110
3111 static void
3112 sc_adjust_ca(struct cursor_attr *cap, int flags, int base, int height)
3113 {
3114         if (flags & CONS_CHARCURSOR_COLORS) {
3115                 cap->bg[0] = base & 0xff;
3116                 cap->bg[1] = height & 0xff;
3117         } else if (flags & CONS_MOUSECURSOR_COLORS) {
3118                 cap->mouse_ba = base & 0xff;
3119                 cap->mouse_ia = height & 0xff;
3120         } else {
3121                 if (base >= 0)
3122                         cap->base = base;
3123                 if (height >= 0)
3124                         cap->height = height;
3125                 if (!(flags & CONS_SHAPEONLY_CURSOR))
3126                         cap->flags = flags & CONS_CURSOR_ATTRS;
3127         }
3128 }
3129
3130 static void
3131 change_cursor_shape(scr_stat *scp, int flags, int base, int height)
3132 {
3133         if ((scp == scp->sc->cur_scp) && !ISGRAPHSC(scp))
3134                 sc_remove_cursor_image(scp);
3135
3136         if (flags & CONS_RESET_CURSOR)
3137                 scp->base_curs_attr = scp->dflt_curs_attr;
3138         else if (flags & CONS_DEFAULT_CURSOR) {
3139                 sc_adjust_ca(&scp->dflt_curs_attr, flags, base, height);
3140                 scp->base_curs_attr = scp->dflt_curs_attr;
3141         } else
3142                 sc_adjust_ca(&scp->base_curs_attr, flags, base, height);
3143
3144         if ((scp == scp->sc->cur_scp) && !ISGRAPHSC(scp)) {
3145                 sc_set_cursor_image(scp);
3146                 sc_draw_cursor_image(scp);
3147         }
3148 }
3149
3150 void
3151 sc_change_cursor_shape(scr_stat *scp, int flags, int base, int height)
3152 {
3153         sc_softc_t *sc;
3154         struct tty *tp;
3155         int s;
3156         int i;
3157
3158         if (flags == -1)
3159                 flags = CONS_SHAPEONLY_CURSOR;
3160
3161         s = spltty();
3162         if (flags & CONS_LOCAL_CURSOR) {
3163                 /* local (per vty) change */
3164                 change_cursor_shape(scp, flags, base, height);
3165                 splx(s);
3166                 return;
3167         }
3168
3169         /* global change */
3170         sc = scp->sc;
3171         if (flags & CONS_RESET_CURSOR)
3172                 sc->curs_attr = sc->dflt_curs_attr;
3173         else if (flags & CONS_DEFAULT_CURSOR) {
3174                 sc_adjust_ca(&sc->dflt_curs_attr, flags, base, height);
3175                 sc->curs_attr = sc->dflt_curs_attr;
3176         } else
3177                 sc_adjust_ca(&sc->curs_attr, flags, base, height);
3178
3179         for (i = sc->first_vty; i < sc->first_vty + sc->vtys; ++i) {
3180                 if ((tp = SC_DEV(sc, i)) == NULL)
3181                         continue;
3182                 if ((scp = sc_get_stat(tp)) == NULL)
3183                         continue;
3184                 scp->dflt_curs_attr = sc->curs_attr;
3185                 change_cursor_shape(scp, CONS_RESET_CURSOR, -1, -1);
3186         }
3187         splx(s);
3188 }
3189
3190 static void
3191 scinit(int unit, int flags)
3192 {
3193
3194         /*
3195          * When syscons is being initialized as the kernel console, malloc()
3196          * is not yet functional, because various kernel structures has not been
3197          * fully initialized yet.  Therefore, we need to declare the following
3198          * static buffers for the console.  This is less than ideal,
3199          * but is necessry evil for the time being.  XXX
3200          */
3201         static u_short sc_buffer[ROW * COL]; /* XXX */
3202 #ifndef SC_NO_FONT_LOADING
3203         static u_char font_8[256 * 8];
3204         static u_char font_14[256 * 14];
3205         static u_char font_16[256 * 16];
3206 #endif
3207
3208 #ifdef SC_KERNEL_CONS_ATTRS
3209         static const u_char dflt_kattrtab[] = SC_KERNEL_CONS_ATTRS;
3210 #elif SC_KERNEL_CONS_ATTR == FG_WHITE
3211         static const u_char dflt_kattrtab[] = {
3212                 FG_WHITE,
3213                 FG_YELLOW,
3214                 FG_LIGHTMAGENTA,
3215                 FG_LIGHTRED,
3216                 FG_LIGHTCYAN,
3217                 FG_LIGHTGREEN,
3218                 FG_LIGHTBLUE,
3219                 FG_GREEN,
3220                 0,
3221         };
3222 #else
3223         static const u_char dflt_kattrtab[] = {
3224                 FG_WHITE,
3225                 0,
3226         };
3227 #endif
3228         sc_softc_t *sc;
3229         scr_stat *scp;
3230         video_adapter_t *adp;
3231         int col;
3232         int row;
3233         int i;
3234
3235         /* one time initialization */
3236         if (init_done == COLD) {
3237                 sc_get_bios_values(&bios_value);
3238                 for (i = 0; i < nitems(sc_kattrtab); i++)
3239                         sc_kattrtab[i] =
3240                             dflt_kattrtab[i % (nitems(dflt_kattrtab) - 1)];
3241         }
3242         init_done = WARM;
3243
3244         /*
3245          * Allocate resources.  Even if we are being called for the second
3246          * time, we must allocate them again, because they might have
3247          * disappeared...
3248          */
3249         sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
3250         if ((sc->flags & SC_INIT_DONE) == 0)
3251                 SC_VIDEO_LOCKINIT(sc);
3252
3253         adp = NULL;
3254         if (sc->adapter >= 0) {
3255                 vid_release(sc->adp, (void *)&sc->adapter);
3256                 adp = sc->adp;
3257                 sc->adp = NULL;
3258         }
3259         if (sc->keyboard >= 0) {
3260                 DPRINTF(5, ("sc%d: releasing kbd%d\n", unit, sc->keyboard));
3261                 i = kbd_release(sc->kbd, (void *)&sc->keyboard);
3262                 DPRINTF(5, ("sc%d: kbd_release returned %d\n", unit, i));
3263                 if (sc->kbd != NULL) {
3264                         DPRINTF(5,
3265                             ("sc%d: kbd != NULL!, index:%d, unit:%d, flags:0x%x\n",
3266                                 unit, sc->kbd->kb_index, sc->kbd->kb_unit,
3267                                 sc->kbd->kb_flags));
3268                 }
3269                 sc->kbd = NULL;
3270         }
3271         sc->adapter = vid_allocate("*", unit, (void *)&sc->adapter);
3272         sc->adp = vid_get_adapter(sc->adapter);
3273         /* assert((sc->adapter >= 0) && (sc->adp != NULL)) */
3274
3275         sc->keyboard = sc_allocate_keyboard(sc, unit);
3276         DPRINTF(1, ("sc%d: keyboard %d\n", unit, sc->keyboard));
3277
3278         sc->kbd = kbd_get_keyboard(sc->keyboard);
3279         if (sc->kbd != NULL) {
3280                 DPRINTF(1,
3281                     ("sc%d: kbd index:%d, unit:%d, flags:0x%x\n", unit,
3282                         sc->kbd->kb_index, sc->kbd->kb_unit,
3283                         sc->kbd->kb_flags));
3284         }
3285
3286         if (!(sc->flags & SC_INIT_DONE) || (adp != sc->adp)) {
3287
3288                 sc->initial_mode = sc->adp->va_initial_mode;
3289
3290 #ifndef SC_NO_FONT_LOADING
3291                 if (flags & SC_KERNEL_CONSOLE) {
3292                         sc->font_8 = font_8;
3293                         sc->font_14 = font_14;
3294                         sc->font_16 = font_16;
3295                 } else if (sc->font_8 == NULL) {
3296                         /* assert(sc_malloc) */
3297                         sc->font_8 = malloc(sizeof(font_8), M_DEVBUF, M_WAITOK);
3298                         sc->font_14 =
3299                             malloc(sizeof(font_14), M_DEVBUF, M_WAITOK);
3300                         sc->font_16 =
3301                             malloc(sizeof(font_16), M_DEVBUF, M_WAITOK);
3302                 }
3303 #endif
3304
3305                 /* extract the hardware cursor location and hide the cursor for
3306                  * now */
3307                 vidd_read_hw_cursor(sc->adp, &col, &row);
3308                 vidd_set_hw_cursor(sc->adp, -1, -1);
3309
3310                 /* set up the first console */
3311                 sc->first_vty = unit * MAXCONS;
3312                 sc->vtys = MAXCONS; /* XXX: should be configurable */
3313                 if (flags & SC_KERNEL_CONSOLE) {
3314                         /*
3315                          * Set up devs structure but don't use it yet, calling
3316                          * make_dev() might panic kernel.  Wait for
3317                          * sc_attach_unit() to actually create the devices.
3318                          */
3319                         sc->dev = main_devs;
3320                         scp = &main_console;
3321                         init_scp(sc, sc->first_vty, scp);
3322                         sc_vtb_init(&scp->vtb, VTB_MEMORY, scp->xsize,
3323                             scp->ysize, (void *)sc_buffer, FALSE);
3324                         if (sc_init_emulator(scp, SC_DFLT_TERM))
3325                                 sc_init_emulator(scp, "*");
3326                         (*scp->tsw->te_default_attr)(
3327                             scp, SC_KERNEL_CONS_ATTR, SC_KERNEL_CONS_REV_ATTR);
3328                 } else {
3329                         /* assert(sc_malloc) */
3330                         sc->dev = malloc(sizeof(struct tty *) * sc->vtys,
3331                             M_DEVBUF, M_WAITOK | M_ZERO);
3332                         sc->dev[0] = sc_alloc_tty(0, unit * MAXCONS);
3333                         scp = alloc_scp(sc, sc->first_vty);
3334                         SC_STAT(sc->dev[0]) = scp;
3335                 }
3336                 sc->cur_scp = scp;
3337
3338 #ifndef __sparc64__
3339                 /* copy screen to temporary buffer */
3340                 sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
3341                     (void *)scp->sc->adp->va_window, FALSE);
3342                 if (ISTEXTSC(scp))
3343                         sc_vtb_copy(&scp->scr, 0, &scp->vtb, 0,
3344                             scp->xsize * scp->ysize);
3345 #endif
3346
3347                 /* Sync h/w cursor position to s/w (sc and teken). */
3348                 if (col >= scp->xsize)
3349                         col = 0;
3350                 if (row >= scp->ysize)
3351                         row = scp->ysize - 1;
3352                 scp->xpos = col;
3353                 scp->ypos = row;
3354                 scp->cursor_pos = scp->cursor_oldpos = row * scp->xsize + col;
3355                 (*scp->tsw->te_sync)(scp);
3356
3357                 sc->dflt_curs_attr.base = 0;
3358                 sc->dflt_curs_attr.height = howmany(scp->font_size, 8);
3359                 sc->dflt_curs_attr.flags = 0;
3360                 sc->dflt_curs_attr.bg[0] = FG_RED;
3361                 sc->dflt_curs_attr.bg[1] = FG_LIGHTGREY;
3362                 sc->dflt_curs_attr.bg[2] = FG_BLUE;
3363                 sc->dflt_curs_attr.mouse_ba = FG_WHITE;
3364                 sc->dflt_curs_attr.mouse_ia = FG_RED;
3365                 sc->curs_attr = sc->dflt_curs_attr;
3366                 scp->base_curs_attr = scp->dflt_curs_attr = sc->curs_attr;
3367                 scp->curs_attr = scp->base_curs_attr;
3368
3369 #ifndef SC_NO_SYSMOUSE
3370                 sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2);
3371 #endif
3372                 if (!ISGRAPHSC(scp)) {
3373                         sc_set_cursor_image(scp);
3374                         sc_draw_cursor_image(scp);
3375                 }
3376
3377                 /* save font and palette */
3378 #ifndef SC_NO_FONT_LOADING
3379                 sc->fonts_loaded = 0;
3380                 if (ISFONTAVAIL(sc->adp->va_flags)) {
3381 #ifdef SC_DFLT_FONT
3382                         bcopy(dflt_font_8, sc->font_8, sizeof(dflt_font_8));
3383                         bcopy(dflt_font_14, sc->font_14, sizeof(dflt_font_14));
3384                         bcopy(dflt_font_16, sc->font_16, sizeof(dflt_font_16));
3385                         sc->fonts_loaded = FONT_16 | FONT_14 | FONT_8;
3386                         if (scp->font_size < 14) {
3387                                 sc_load_font(scp, 0, 8, 8, sc->font_8, 0, 256);
3388                         } else if (scp->font_size >= 16) {
3389                                 sc_load_font(
3390                                     scp, 0, 16, 8, sc->font_16, 0, 256);
3391                         } else {
3392                                 sc_load_font(
3393                                     scp, 0, 14, 8, sc->font_14, 0, 256);
3394                         }
3395 #else /* !SC_DFLT_FONT */
3396                         if (scp->font_size < 14) {
3397                                 sc_save_font(scp, 0, 8, 8, sc->font_8, 0, 256);
3398                                 sc->fonts_loaded = FONT_8;
3399                         } else if (scp->font_size >= 16) {
3400                                 sc_save_font(
3401                                     scp, 0, 16, 8, sc->font_16, 0, 256);
3402                                 sc->fonts_loaded = FONT_16;
3403                         } else {
3404                                 sc_save_font(
3405                                     scp, 0, 14, 8, sc->font_14, 0, 256);
3406                                 sc->fonts_loaded = FONT_14;
3407                         }
3408 #endif /* SC_DFLT_FONT */
3409                         /* FONT KLUDGE: always use the font page #0. XXX */
3410                         sc_show_font(scp, 0);
3411                 }
3412 #endif /* !SC_NO_FONT_LOADING */
3413
3414 #ifndef SC_NO_PALETTE_LOADING
3415                 vidd_save_palette(sc->adp, sc->palette);
3416 #ifdef SC_PIXEL_MODE
3417                 for (i = 0; i < sizeof(sc->palette2); i++)
3418                         sc->palette2[i] = i / 3;
3419 #endif
3420 #endif
3421
3422 #ifdef DEV_SPLASH
3423                 if (!(sc->flags & SC_SPLASH_SCRN)) {
3424                         /* we are ready to put up the splash image! */
3425                         splash_init(sc->adp, scsplash_callback, sc);
3426                         sc->flags |= SC_SPLASH_SCRN;
3427                 }
3428 #endif
3429         }
3430
3431         /* the rest is not necessary, if we have done it once */
3432         if (sc->flags & SC_INIT_DONE)
3433                 return;
3434
3435         /* initialize mapscrn arrays to a one to one map */
3436         for (i = 0; i < sizeof(sc->scr_map); i++)
3437                 sc->scr_map[i] = sc->scr_rmap[i] = i;
3438
3439         sc->flags |= SC_INIT_DONE;
3440 }
3441
3442 static void
3443 scterm(int unit, int flags)
3444 {
3445         sc_softc_t *sc;
3446         scr_stat *scp;
3447
3448         sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
3449         if (sc == NULL)
3450                 return; /* shouldn't happen */
3451
3452 #ifdef DEV_SPLASH
3453         /* this console is no longer available for the splash screen */
3454         if (sc->flags & SC_SPLASH_SCRN) {
3455                 splash_term(sc->adp);
3456                 sc->flags &= ~SC_SPLASH_SCRN;
3457         }
3458 #endif
3459
3460 #if 0 /* XXX */
3461     /* move the hardware cursor to the upper-left corner */
3462     vidd_set_hw_cursor(sc->adp, 0, 0);
3463 #endif
3464
3465         /* release the keyboard and the video card */
3466         if (sc->keyboard >= 0)
3467                 kbd_release(sc->kbd, &sc->keyboard);
3468         if (sc->adapter >= 0)
3469                 vid_release(sc->adp, &sc->adapter);
3470
3471         /* stop the terminal emulator, if any */
3472         scp = sc_get_stat(sc->dev[0]);
3473         if (scp->tsw)
3474                 (*scp->tsw->te_term)(scp, &scp->ts);
3475         mtx_destroy(&sc->video_mtx);
3476
3477         /* clear the structure */
3478         if (!(flags & SC_KERNEL_CONSOLE)) {
3479                 free(scp->ts, M_DEVBUF);
3480                 /* XXX: We need delete_dev() for this */
3481                 free(sc->dev, M_DEVBUF);
3482 #if 0
3483         /* XXX: We need a ttyunregister for this */
3484         free(sc->tty, M_DEVBUF);
3485 #endif
3486 #ifndef SC_NO_FONT_LOADING
3487                 free(sc->font_8, M_DEVBUF);
3488                 free(sc->font_14, M_DEVBUF);
3489                 free(sc->font_16, M_DEVBUF);
3490 #endif
3491                 /* XXX vtb, history */
3492         }
3493         bzero(sc, sizeof(*sc));
3494         sc->keyboard = -1;
3495         sc->adapter = -1;
3496 }
3497
3498 static void
3499 scshutdown(__unused void *arg, __unused int howto)
3500 {
3501
3502         KASSERT(sc_console != NULL, ("sc_console != NULL"));
3503         KASSERT(sc_console->sc != NULL, ("sc_console->sc != NULL"));
3504         KASSERT(sc_console->sc->cur_scp != NULL,
3505             ("sc_console->sc->cur_scp != NULL"));
3506
3507         sc_touch_scrn_saver();
3508         if (!cold && sc_console->sc->cur_scp->index != sc_console->index &&
3509             sc_console->sc->cur_scp->smode.mode == VT_AUTO &&
3510             sc_console->smode.mode == VT_AUTO)
3511                 sc_switch_scr(sc_console->sc, sc_console->index);
3512         shutdown_in_progress = TRUE;
3513 }
3514
3515 static void
3516 scsuspend(__unused void *arg)
3517 {
3518         int retry;
3519
3520         KASSERT(sc_console != NULL, ("sc_console != NULL"));
3521         KASSERT(sc_console->sc != NULL, ("sc_console->sc != NULL"));
3522         KASSERT(sc_console->sc->cur_scp != NULL,
3523             ("sc_console->sc->cur_scp != NULL"));
3524
3525         sc_susp_scr = sc_console->sc->cur_scp->index;
3526         if (sc_no_suspend_vtswitch || sc_susp_scr == sc_console->index) {
3527                 sc_touch_scrn_saver();
3528                 sc_susp_scr = -1;
3529                 return;
3530         }
3531         for (retry = 0; retry < 10; retry++) {
3532                 sc_switch_scr(sc_console->sc, sc_console->index);
3533                 if (!sc_console->sc->switch_in_progress)
3534                         break;
3535                 pause("scsuspend", hz);
3536         }
3537         suspend_in_progress = TRUE;
3538 }
3539
3540 static void
3541 scresume(__unused void *arg)
3542 {
3543
3544         KASSERT(sc_console != NULL, ("sc_console != NULL"));
3545         KASSERT(sc_console->sc != NULL, ("sc_console->sc != NULL"));
3546         KASSERT(sc_console->sc->cur_scp != NULL,
3547             ("sc_console->sc->cur_scp != NULL"));
3548
3549         suspend_in_progress = FALSE;
3550         if (sc_susp_scr < 0) {
3551                 update_font(sc_console->sc->cur_scp);
3552                 return;
3553         }
3554         sc_switch_scr(sc_console->sc, sc_susp_scr);
3555 }
3556
3557 int
3558 sc_clean_up(scr_stat *scp)
3559 {
3560 #ifdef DEV_SPLASH
3561         int error;
3562 #endif
3563
3564         if (scp->sc->flags & SC_SCRN_BLANKED) {
3565                 sc_touch_scrn_saver();
3566 #ifdef DEV_SPLASH
3567                 if ((error = wait_scrn_saver_stop(scp->sc)))
3568                         return error;
3569 #endif
3570         }
3571         scp->status |= MOUSE_HIDDEN;
3572         sc_remove_mouse_image(scp);
3573         sc_remove_cutmarking(scp);
3574         return 0;
3575 }
3576
3577 void
3578 sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard)
3579 {
3580         sc_vtb_t new;
3581         sc_vtb_t old;
3582
3583         old = scp->vtb;
3584         sc_vtb_init(&new, VTB_MEMORY, scp->xsize, scp->ysize, NULL, wait);
3585         if (!discard && (old.vtb_flags & VTB_VALID)) {
3586                 /* retain the current cursor position and buffer contants */
3587                 scp->cursor_oldpos = scp->cursor_pos;
3588                 /*
3589                  * This works only if the old buffer has the same size as or
3590                  * larger than the new one. XXX
3591                  */
3592                 sc_vtb_copy(&old, 0, &new, 0, scp->xsize * scp->ysize);
3593                 scp->vtb = new;
3594         } else {
3595                 scp->vtb = new;
3596                 sc_vtb_destroy(&old);
3597         }
3598
3599 #ifndef SC_NO_SYSMOUSE
3600         /* move the mouse cursor at the center of the screen */
3601         sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2);
3602 #endif
3603 }
3604
3605 static scr_stat *
3606 alloc_scp(sc_softc_t *sc, int vty)
3607 {
3608         scr_stat *scp;
3609
3610         /* assert(sc_malloc) */
3611
3612         scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK);
3613         init_scp(sc, vty, scp);
3614
3615         sc_alloc_scr_buffer(scp, TRUE, TRUE);
3616         if (sc_init_emulator(scp, SC_DFLT_TERM))
3617                 sc_init_emulator(scp, "*");
3618
3619 #ifndef SC_NO_CUTPASTE
3620         sc_alloc_cut_buffer(scp, TRUE);
3621 #endif
3622
3623 #ifndef SC_NO_HISTORY
3624         sc_alloc_history_buffer(scp, 0, 0, TRUE);
3625 #endif
3626
3627         return scp;
3628 }
3629
3630 static void
3631 init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
3632 {
3633         video_info_t info;
3634
3635         bzero(scp, sizeof(*scp));
3636
3637         scp->index = vty;
3638         scp->sc = sc;
3639         scp->status = 0;
3640         scp->mode = sc->initial_mode;
3641         vidd_get_info(sc->adp, scp->mode, &info);
3642         if (info.vi_flags & V_INFO_GRAPHICS) {
3643                 scp->status |= GRAPHICS_MODE;
3644                 scp->xpixel = info.vi_width;
3645                 scp->ypixel = info.vi_height;
3646                 scp->xsize = info.vi_width / info.vi_cwidth;
3647                 scp->ysize = info.vi_height / info.vi_cheight;
3648                 scp->font_size = 0;
3649                 scp->font = NULL;
3650         } else {
3651                 scp->xsize = info.vi_width;
3652                 scp->ysize = info.vi_height;
3653                 scp->xpixel = scp->xsize * info.vi_cwidth;
3654                 scp->ypixel = scp->ysize * info.vi_cheight;
3655         }
3656
3657         scp->font_size = info.vi_cheight;
3658         scp->font_width = info.vi_cwidth;
3659 #ifndef SC_NO_FONT_LOADING
3660         if (info.vi_cheight < 14)
3661                 scp->font = sc->font_8;
3662         else if (info.vi_cheight >= 16)
3663                 scp->font = sc->font_16;
3664         else
3665                 scp->font = sc->font_14;
3666 #else
3667         scp->font = NULL;
3668 #endif
3669
3670         sc_vtb_init(&scp->vtb, VTB_MEMORY, 0, 0, NULL, FALSE);
3671 #ifndef __sparc64__
3672         sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, 0, 0, NULL, FALSE);
3673 #endif
3674         scp->xoff = scp->yoff = 0;
3675         scp->xpos = scp->ypos = 0;
3676         scp->start = scp->xsize * scp->ysize - 1;
3677         scp->end = 0;
3678         scp->tsw = NULL;
3679         scp->ts = NULL;
3680         scp->rndr = NULL;
3681         scp->border = (SC_NORM_ATTR >> 4) & 0x0f;
3682         scp->base_curs_attr = scp->dflt_curs_attr = sc->curs_attr;
3683         scp->mouse_cut_start = scp->xsize * scp->ysize;
3684         scp->mouse_cut_end = -1;
3685         scp->mouse_signal = 0;
3686         scp->mouse_pid = 0;
3687         scp->mouse_proc = NULL;
3688         scp->kbd_mode = K_XLATE;
3689         scp->bell_pitch = bios_value.bell_pitch;
3690         scp->bell_duration = BELL_DURATION;
3691         scp->status |= (bios_value.shift_state & NLKED);
3692         scp->status |= CURSOR_ENABLED | MOUSE_HIDDEN;
3693         scp->pid = 0;
3694         scp->proc = NULL;
3695         scp->smode.mode = VT_AUTO;
3696         scp->history = NULL;
3697         scp->history_pos = 0;
3698         scp->history_size = 0;
3699 }
3700
3701 int
3702 sc_init_emulator(scr_stat *scp, char *name)
3703 {
3704         sc_term_sw_t *sw;
3705         sc_rndr_sw_t *rndr;
3706         void *p;
3707         int error;
3708
3709         if (name == NULL) /* if no name is given, use the current emulator */
3710                 sw = scp->tsw;
3711         else /* ...otherwise find the named emulator */
3712                 sw = sc_term_match(name);
3713         if (sw == NULL)
3714                 return EINVAL;
3715
3716         rndr = NULL;
3717         if (strcmp(sw->te_renderer, "*") != 0) {
3718                 rndr = sc_render_match(scp, sw->te_renderer,
3719                     scp->status & (GRAPHICS_MODE | PIXEL_MODE));
3720         }
3721         if (rndr == NULL) {
3722                 rndr = sc_render_match(scp, scp->sc->adp->va_name,
3723                     scp->status & (GRAPHICS_MODE | PIXEL_MODE));
3724                 if (rndr == NULL)
3725                         return ENODEV;
3726         }
3727
3728         if (sw == scp->tsw) {
3729                 error = (*sw->te_init)(scp, &scp->ts, SC_TE_WARM_INIT);
3730                 scp->rndr = rndr;
3731                 scp->rndr->init(scp);
3732                 sc_clear_screen(scp);
3733                 /* assert(error == 0); */
3734                 return error;
3735         }
3736
3737         if (sc_malloc && (sw->te_size > 0))
3738                 p = malloc(sw->te_size, M_DEVBUF, M_NOWAIT);
3739         else
3740                 p = NULL;
3741         error = (*sw->te_init)(scp, &p, SC_TE_COLD_INIT);
3742         if (error)
3743                 return error;
3744
3745         if (scp->tsw)
3746                 (*scp->tsw->te_term)(scp, &scp->ts);
3747         if (scp->ts != NULL)
3748                 free(scp->ts, M_DEVBUF);
3749         scp->tsw = sw;
3750         scp->ts = p;
3751         scp->rndr = rndr;
3752         scp->rndr->init(scp);
3753
3754         (*sw->te_default_attr)(scp, SC_NORM_ATTR, SC_NORM_REV_ATTR);
3755         sc_clear_screen(scp);
3756
3757         return 0;
3758 }
3759
3760 /*
3761  * scgetc(flags) - get character from keyboard.
3762  * If flags & SCGETC_CN, then avoid harmful side effects.
3763  * If flags & SCGETC_NONBLOCK, then wait until a key is pressed, else
3764  * return NOKEY if there is nothing there.
3765  */
3766 static u_int
3767 scgetc(sc_softc_t *sc, u_int flags, struct sc_cnstate *sp)
3768 {
3769         scr_stat *scp;
3770 #ifndef SC_NO_HISTORY
3771         struct tty *tp;
3772 #endif
3773         u_int c;
3774         int this_scr;
3775         int f;
3776         int i;
3777
3778         if (sc->kbd == NULL)
3779                 return NOKEY;
3780
3781 next_code:
3782 #if 1
3783         /* I don't like this, but... XXX */
3784         if (flags & SCGETC_CN)
3785                 sccnupdate(sc->cur_scp);
3786 #endif
3787         scp = sc->cur_scp;
3788         /* first see if there is something in the keyboard port */
3789         for (;;) {
3790                 if (flags & SCGETC_CN)
3791                         sccnscrunlock(sc, sp);
3792                 c = kbdd_read_char(sc->kbd, !(flags & SCGETC_NONBLOCK));
3793                 if (flags & SCGETC_CN)
3794                         sccnscrlock(sc, sp);
3795                 if (c == ERRKEY) {
3796                         if (!(flags & SCGETC_CN))
3797                                 sc_bell(
3798                                     scp, bios_value.bell_pitch, BELL_DURATION);
3799                 } else if (c == NOKEY)
3800                         return c;
3801                 else
3802                         break;
3803         }
3804
3805         /* make screensaver happy */
3806         if (!(c & RELKEY))
3807                 sc_touch_scrn_saver();
3808
3809         if (!(flags & SCGETC_CN))
3810                 random_harvest_queue(&c, sizeof(c), RANDOM_KEYBOARD);
3811
3812         if (sc->kbd_open_level == 0 && scp->kbd_mode != K_XLATE)
3813                 return KEYCHAR(c);
3814
3815         /* if scroll-lock pressed allow history browsing */
3816         if (!ISGRAPHSC(scp) && scp->history && scp->status & SLKED) {
3817
3818                 scp->status &= ~CURSOR_ENABLED;
3819                 sc_remove_cursor_image(scp);
3820
3821 #ifndef SC_NO_HISTORY
3822                 if (!(scp->status & BUFFER_SAVED)) {
3823                         scp->status |= BUFFER_SAVED;
3824                         sc_hist_save(scp);
3825                 }
3826                 switch (c) {
3827                 /* FIXME: key codes */
3828                 case SPCLKEY | FKEY | F(49): /* home key */
3829                         sc_remove_cutmarking(scp);
3830                         sc_hist_home(scp);
3831                         goto next_code;
3832
3833                 case SPCLKEY | FKEY | F(57): /* end key */
3834                         sc_remove_cutmarking(scp);
3835                         sc_hist_end(scp);
3836                         goto next_code;
3837
3838                 case SPCLKEY | FKEY | F(50): /* up arrow key */
3839                         sc_remove_cutmarking(scp);
3840                         if (sc_hist_up_line(scp))
3841                                 if (!(flags & SCGETC_CN))
3842                                         sc_bell(scp, bios_value.bell_pitch,
3843                                             BELL_DURATION);
3844                         goto next_code;
3845
3846                 case SPCLKEY | FKEY | F(58): /* down arrow key */
3847                         sc_remove_cutmarking(scp);
3848                         if (sc_hist_down_line(scp))
3849                                 if (!(flags & SCGETC_CN))
3850                                         sc_bell(scp, bios_value.bell_pitch,
3851                                             BELL_DURATION);
3852                         goto next_code;
3853
3854                 case SPCLKEY | FKEY | F(51): /* page up key */
3855                         sc_remove_cutmarking(scp);
3856                         for (i = 0; i < scp->ysize; i++)
3857                                 if (sc_hist_up_line(scp)) {
3858                                         if (!(flags & SCGETC_CN))
3859                                                 sc_bell(scp,
3860                                                     bios_value.bell_pitch,
3861                                                     BELL_DURATION);
3862                                         break;
3863                                 }
3864                         goto next_code;
3865
3866                 case SPCLKEY | FKEY | F(59): /* page down key */
3867                         sc_remove_cutmarking(scp);
3868                         for (i = 0; i < scp->ysize; i++)
3869                                 if (sc_hist_down_line(scp)) {
3870                                         if (!(flags & SCGETC_CN))
3871                                                 sc_bell(scp,
3872                                                     bios_value.bell_pitch,
3873                                                     BELL_DURATION);
3874                                         break;
3875                                 }
3876                         goto next_code;
3877                 }
3878 #endif /* SC_NO_HISTORY */
3879         }
3880
3881         /*
3882          * Process and consume special keys here.  Return a plain char code
3883          * or a char code with the META flag or a function key code.
3884          */
3885         if (c & RELKEY) {
3886                 /* key released */
3887                 /* goto next_code */
3888         } else {
3889                 /* key pressed */
3890                 if (c & SPCLKEY) {
3891                         c &= ~SPCLKEY;
3892                         switch (KEYCHAR(c)) {
3893                         /* LOCKING KEYS */
3894                         case NLK:
3895                         case CLK:
3896                         case ALK:
3897                                 break;
3898                         case SLK:
3899                                 (void)kbdd_ioctl(
3900                                     sc->kbd, KDGKBSTATE, (caddr_t)&f);
3901                                 if (f & SLKED) {
3902                                         scp->status |= SLKED;
3903                                 } else {
3904                                         if (scp->status & SLKED) {
3905                                                 scp->status &= ~SLKED;
3906 #ifndef SC_NO_HISTORY
3907                                                 if (scp->status &
3908                                                     BUFFER_SAVED) {
3909                                                         if (!sc_hist_restore(
3910                                                                 scp))
3911                                                                 sc_remove_cutmarking(
3912                                                                     scp);
3913                                                         scp->status &=
3914                                                             ~BUFFER_SAVED;
3915                                                         scp->status |=
3916                                                             CURSOR_ENABLED;
3917                                                         sc_draw_cursor_image(
3918                                                             scp);
3919                                                 }
3920                                                 /* Only safe in Giant-locked
3921                                                  * context. */
3922                                                 tp = SC_DEV(sc, scp->index);
3923                                                 if (!(flags & SCGETC_CN) &&
3924                                                     tty_opened_ns(tp))
3925                                                         sctty_outwakeup(tp);
3926 #endif
3927                                         }
3928                                 }
3929                                 break;
3930
3931                         case PASTE:
3932 #ifndef SC_NO_CUTPASTE
3933                                 sc_mouse_paste(scp);
3934 #endif
3935                                 break;
3936
3937                         /* NON-LOCKING KEYS */
3938                         case NOP:
3939                         case LSH:
3940                         case RSH:
3941                         case LCTR:
3942                         case RCTR:
3943                         case LALT:
3944                         case RALT:
3945                         case ASH:
3946                         case META:
3947                                 break;
3948
3949                         case BTAB:
3950                                 if (!(sc->flags & SC_SCRN_BLANKED))
3951                                         return c;
3952                                 break;
3953
3954                         case SPSC:
3955 #ifdef DEV_SPLASH
3956                                 /* force activatation/deactivation of the screen
3957                                  * saver */
3958                                 if (!(sc->flags & SC_SCRN_BLANKED)) {
3959                                         run_scrn_saver = TRUE;
3960                                         sc->scrn_time_stamp -= scrn_blank_time;
3961                                 }
3962                                 if (cold) {
3963                                         /*
3964                                          * While devices are being probed, the
3965                                          * screen saver need to be invoked
3966                                          * explicitly. XXX
3967                                          */
3968                                         if (sc->flags & SC_SCRN_BLANKED) {
3969                                                 scsplash_stick(FALSE);
3970                                                 stop_scrn_saver(
3971                                                     sc, current_saver);
3972                                         } else {
3973                                                 if (!ISGRAPHSC(scp)) {
3974                                                         scsplash_stick(TRUE);
3975                                                         (*current_saver)(
3976                                                             sc, TRUE);
3977                                                 }
3978                                         }
3979                                 }
3980 #endif /* DEV_SPLASH */
3981                                 break;
3982
3983                         case RBT:
3984 #ifndef SC_DISABLE_REBOOT
3985                                 if (enable_reboot && !(flags & SCGETC_CN))
3986                                         shutdown_nice(0);
3987 #endif
3988                                 break;
3989
3990                         case HALT:
3991 #ifndef SC_DISABLE_REBOOT
3992                                 if (enable_reboot && !(flags & SCGETC_CN))
3993                                         shutdown_nice(RB_HALT);
3994 #endif
3995                                 break;
3996
3997                         case PDWN:
3998 #ifndef SC_DISABLE_REBOOT
3999                                 if (enable_reboot && !(flags & SCGETC_CN))
4000                                         shutdown_nice(RB_HALT | RB_POWEROFF);
4001 #endif
4002                                 break;
4003
4004                         case SUSP:
4005                                 power_pm_suspend(POWER_SLEEP_STATE_SUSPEND);
4006                                 break;
4007                         case STBY:
4008                                 power_pm_suspend(POWER_SLEEP_STATE_STANDBY);
4009                                 break;
4010
4011                         case DBG:
4012 #ifndef SC_DISABLE_KDBKEY
4013                                 if (enable_kdbkey)
4014                                         kdb_break();
4015 #endif
4016                                 break;
4017
4018                         case PNC:
4019                                 if (enable_panic_key)
4020                                         panic("Forced by the panic key");
4021                                 break;
4022
4023                         case NEXT:
4024                                 this_scr = scp->index;
4025                                 for (i = (this_scr - sc->first_vty + 1) %
4026                                          sc->vtys;
4027                                      sc->first_vty + i != this_scr;
4028                                      i = (i + 1) % sc->vtys) {
4029                                         struct tty *tp =
4030                                             SC_DEV(sc, sc->first_vty + i);
4031                                         if (tty_opened_ns(tp)) {
4032                                                 sc_switch_scr(
4033                                                     scp->sc, sc->first_vty + i);
4034                                                 break;
4035                                         }
4036                                 }
4037                                 break;
4038
4039                         case PREV:
4040                                 this_scr = scp->index;
4041                                 for (i = (this_scr - sc->first_vty + sc->vtys -
4042                                              1) %
4043                                          sc->vtys;
4044                                      sc->first_vty + i != this_scr;
4045                                      i = (i + sc->vtys - 1) % sc->vtys) {
4046                                         struct tty *tp =
4047                                             SC_DEV(sc, sc->first_vty + i);
4048                                         if (tty_opened_ns(tp)) {
4049                                                 sc_switch_scr(
4050                                                     scp->sc, sc->first_vty + i);
4051                                                 break;
4052                                         }
4053                                 }
4054                                 break;
4055
4056                         default:
4057                                 if (KEYCHAR(c) >= F_SCR &&
4058                                     KEYCHAR(c) <= L_SCR) {
4059                                         sc_switch_scr(scp->sc,
4060                                             sc->first_vty + KEYCHAR(c) - F_SCR);
4061                                         break;
4062                                 }
4063                                 /* assert(c & FKEY) */
4064                                 if (!(sc->flags & SC_SCRN_BLANKED))
4065                                         return c;
4066                                 break;
4067                         }
4068                         /* goto next_code */
4069                 } else {
4070                         /* regular keys (maybe MKEY is set) */
4071 #if !defined(SC_DISABLE_KDBKEY) && defined(KDB)
4072                         if (enable_kdbkey)
4073                                 kdb_alt_break(c, &sc->sc_altbrk);
4074 #endif
4075                         if (!(sc->flags & SC_SCRN_BLANKED))
4076                                 return c;
4077                 }
4078         }
4079
4080         goto next_code;
4081 }
4082
4083 static int
4084 sctty_mmap(struct tty *tp, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot,
4085     vm_memattr_t *memattr)
4086 {
4087         scr_stat *scp;
4088
4089         scp = sc_get_stat(tp);
4090         if (scp != scp->sc->cur_scp)
4091                 return -1;
4092         return vidd_mmap(scp->sc->adp, offset, paddr, nprot, memattr);
4093 }
4094
4095 static void
4096 update_font(scr_stat *scp)
4097 {
4098 #ifndef SC_NO_FONT_LOADING
4099         /* load appropriate font */
4100         if (!(scp->status & GRAPHICS_MODE)) {
4101                 if (!(scp->status & PIXEL_MODE) &&
4102                     ISFONTAVAIL(scp->sc->adp->va_flags)) {
4103                         if (scp->font_size < 14) {
4104                                 if (scp->sc->fonts_loaded & FONT_8)
4105                                         sc_load_font(scp, 0, 8, 8,
4106                                             scp->sc->font_8, 0, 256);
4107                         } else if (scp->font_size >= 16) {
4108                                 if (scp->sc->fonts_loaded & FONT_16)
4109                                         sc_load_font(scp, 0, 16, 8,
4110                                             scp->sc->font_16, 0, 256);
4111                         } else {
4112                                 if (scp->sc->fonts_loaded & FONT_14)
4113                                         sc_load_font(scp, 0, 14, 8,
4114                                             scp->sc->font_14, 0, 256);
4115                         }
4116                         /*
4117                          * FONT KLUDGE:
4118                          * This is an interim kludge to display correct font.
4119                          * Always use the font page #0 on the video plane 2.
4120                          * Somehow we cannot show the font in other font pages
4121                          * on some video cards... XXX
4122                          */
4123                         sc_show_font(scp, 0);
4124                 }
4125                 mark_all(scp);
4126         }
4127 #endif /* !SC_NO_FONT_LOADING */
4128 }
4129
4130 static int
4131 save_kbd_state(scr_stat *scp)
4132 {
4133         int state;
4134         int error;
4135
4136         error = kbdd_ioctl(scp->sc->kbd, KDGKBSTATE, (caddr_t)&state);
4137         if (error == ENOIOCTL)
4138                 error = ENODEV;
4139         if (error == 0) {
4140                 scp->status &= ~LOCK_MASK;
4141                 scp->status |= state;
4142         }
4143         return error;
4144 }
4145
4146 static int
4147 update_kbd_state(scr_stat *scp, int new_bits, int mask)
4148 {
4149         int state;
4150         int error;
4151
4152         if (mask != LOCK_MASK) {
4153                 error = kbdd_ioctl(scp->sc->kbd, KDGKBSTATE, (caddr_t)&state);
4154                 if (error == ENOIOCTL)
4155                         error = ENODEV;
4156                 if (error)
4157                         return error;
4158                 state &= ~mask;
4159                 state |= new_bits & mask;
4160         } else {
4161                 state = new_bits & LOCK_MASK;
4162         }
4163         error = kbdd_ioctl(scp->sc->kbd, KDSKBSTATE, (caddr_t)&state);
4164         if (error == ENOIOCTL)
4165                 error = ENODEV;
4166         return error;
4167 }
4168
4169 static int
4170 update_kbd_leds(scr_stat *scp, int which)
4171 {
4172         int error;
4173
4174         which &= LOCK_MASK;
4175         error = kbdd_ioctl(scp->sc->kbd, KDSETLED, (caddr_t)&which);
4176         if (error == ENOIOCTL)
4177                 error = ENODEV;
4178         return error;
4179 }
4180
4181 int
4182 set_mode(scr_stat *scp)
4183 {
4184         video_info_t info;
4185
4186         /* reject unsupported mode */
4187         if (vidd_get_info(scp->sc->adp, scp->mode, &info))
4188                 return 1;
4189
4190         /* if this vty is not currently showing, do nothing */
4191         if (scp != scp->sc->cur_scp)
4192                 return 0;
4193
4194         /* setup video hardware for the given mode */
4195         vidd_set_mode(scp->sc->adp, scp->mode);
4196         scp->rndr->init(scp);
4197 #ifndef __sparc64__
4198         sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
4199             (void *)scp->sc->adp->va_window, FALSE);
4200 #endif
4201
4202         update_font(scp);
4203
4204         sc_set_border(scp, scp->border);
4205         sc_set_cursor_image(scp);
4206
4207         return 0;
4208 }
4209
4210 void
4211 sc_set_border(scr_stat *scp, int color)
4212 {
4213         SC_VIDEO_LOCK(scp->sc);
4214         (*scp->rndr->draw_border)(scp, color);
4215         SC_VIDEO_UNLOCK(scp->sc);
4216 }
4217
4218 #ifndef SC_NO_FONT_LOADING
4219 void
4220 sc_load_font(scr_stat *scp, int page, int size, int width, u_char *buf,
4221     int base, int count)
4222 {
4223         sc_softc_t *sc;
4224
4225         sc = scp->sc;
4226         sc->font_loading_in_progress = TRUE;
4227         vidd_load_font(sc->adp, page, size, width, buf, base, count);
4228         sc->font_loading_in_progress = FALSE;
4229 }
4230
4231 void
4232 sc_save_font(scr_stat *scp, int page, int size, int width, u_char *buf,
4233     int base, int count)
4234 {
4235         sc_softc_t *sc;
4236
4237         sc = scp->sc;
4238         sc->font_loading_in_progress = TRUE;
4239         vidd_save_font(sc->adp, page, size, width, buf, base, count);
4240         sc->font_loading_in_progress = FALSE;
4241 }
4242
4243 void
4244 sc_show_font(scr_stat *scp, int page)
4245 {
4246         vidd_show_font(scp->sc->adp, page);
4247 }
4248 #endif /* !SC_NO_FONT_LOADING */
4249
4250 void
4251 sc_paste(scr_stat *scp, const u_char *p, int count)
4252 {
4253         struct tty *tp;
4254         u_char *rmap;
4255
4256         tp = SC_DEV(scp->sc, scp->sc->cur_scp->index);
4257         if (!tty_opened_ns(tp))
4258                 return;
4259         rmap = scp->sc->scr_rmap;
4260         for (; count > 0; --count)
4261                 ttydisc_rint(tp, rmap[*p++], 0);
4262         ttydisc_rint_done(tp);
4263 }
4264
4265 void
4266 sc_respond(scr_stat *scp, const u_char *p, int count, int wakeup)
4267 {
4268         struct tty *tp;
4269
4270         tp = SC_DEV(scp->sc, scp->sc->cur_scp->index);
4271         if (!tty_opened_ns(tp))
4272                 return;
4273         ttydisc_rint_simple(tp, p, count);
4274         if (wakeup) {
4275                 /* XXX: we can't always call ttydisc_rint_done() here! */
4276                 ttydisc_rint_done(tp);
4277         }
4278 }
4279
4280 void
4281 sc_bell(scr_stat *scp, int pitch, int duration)
4282 {
4283         if (cold || kdb_active || shutdown_in_progress || !enable_bell)
4284                 return;
4285
4286         if (scp != scp->sc->cur_scp && (scp->sc->flags & SC_QUIET_BELL))
4287                 return;
4288
4289         if (scp->sc->flags & SC_VISUAL_BELL) {
4290                 if (scp->sc->blink_in_progress)
4291                         return;
4292                 scp->sc->blink_in_progress = 3;
4293                 if (scp != scp->sc->cur_scp)
4294                         scp->sc->blink_in_progress += 2;
4295                 blink_screen(scp->sc->cur_scp);
4296         } else if (duration != 0 && pitch != 0) {
4297                 if (scp != scp->sc->cur_scp)
4298                         pitch *= 2;
4299                 sysbeep(1193182 / pitch, duration);
4300         }
4301 }
4302
4303 static int
4304 sc_kattr(void)
4305 {
4306         if (sc_console == NULL)
4307                 return (SC_KERNEL_CONS_ATTR); /* for very early, before pcpu */
4308         return (sc_kattrtab[curcpu % nitems(sc_kattrtab)]);
4309 }
4310
4311 static void
4312 blink_screen(void *arg)
4313 {
4314         scr_stat *scp = arg;
4315         struct tty *tp;
4316
4317         if (ISGRAPHSC(scp) || (scp->sc->blink_in_progress <= 1)) {
4318                 scp->sc->blink_in_progress = 0;
4319                 mark_all(scp);
4320                 tp = SC_DEV(scp->sc, scp->index);
4321                 if (tty_opened_ns(tp))
4322                         sctty_outwakeup(tp);
4323                 if (scp->sc->delayed_next_scr)
4324                         sc_switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
4325         } else {
4326                 (*scp->rndr->draw)(scp, 0, scp->xsize * scp->ysize,
4327                     scp->sc->blink_in_progress & 1);
4328                 scp->sc->blink_in_progress--;
4329                 callout_reset_sbt(&scp->sc->cblink, SBT_1S / 15, 0,
4330                     blink_screen, scp, C_PREL(0));
4331         }
4332 }
4333
4334 /*
4335  * Until sc_attach_unit() gets called no dev structures will be available
4336  * to store the per-screen current status.  This is the case when the
4337  * kernel is initially booting and needs access to its console.  During
4338  * this early phase of booting the console's current status is kept in
4339  * one statically defined scr_stat structure, and any pointers to the
4340  * dev structures will be NULL.
4341  */
4342
4343 static scr_stat *
4344 sc_get_stat(struct tty *tp)
4345 {
4346         if (tp == NULL)
4347                 return (&main_console);
4348         return (SC_STAT(tp));
4349 }
4350
4351 /*
4352  * Allocate active keyboard. Try to allocate "kbdmux" keyboard first, and,
4353  * if found, add all non-busy keyboards to "kbdmux". Otherwise look for
4354  * any keyboard.
4355  */
4356
4357 static int
4358 sc_allocate_keyboard(sc_softc_t *sc, int unit)
4359 {
4360         int idx0, idx;
4361         keyboard_t *k0, *k;
4362         keyboard_info_t ki;
4363
4364         idx0 =
4365             kbd_allocate("kbdmux", -1, (void *)&sc->keyboard, sckbdevent, sc);
4366         if (idx0 != -1) {
4367                 k0 = kbd_get_keyboard(idx0);
4368
4369                 for (idx = kbd_find_keyboard2("*", -1, 0); idx != -1;
4370                      idx = kbd_find_keyboard2("*", -1, idx + 1)) {
4371                         k = kbd_get_keyboard(idx);
4372
4373                         if (idx == idx0 || KBD_IS_BUSY(k))
4374                                 continue;
4375
4376                         bzero(&ki, sizeof(ki));
4377                         strcpy(ki.kb_name, k->kb_name);
4378                         ki.kb_unit = k->kb_unit;
4379
4380                         (void)kbdd_ioctl(k0, KBADDKBD, (caddr_t)&ki);
4381                 }
4382         } else
4383                 idx0 = kbd_allocate(
4384                     "*", unit, (void *)&sc->keyboard, sckbdevent, sc);
4385
4386         return (idx0);
4387 }