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