LINT build test. Aggregated source code adjustments to bring most of the
[dragonfly.git] / sys / dev / video / pcvt / i386 / pcvt_drv.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1999 Hellmuth Michaelis
3 *
4 * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
5 *
6 * Copyright (c) 1992, 1993 Brian Dunford-Shore and Scott Turner.
7 *
8 * Copyright (c) 1993 Charles Hannum.
9 *
10 * All rights reserved.
11 *
12 * Parts of this code regarding the NetBSD interface were written
13 * by Charles Hannum.
14 *
15 * This code is derived from software contributed to Berkeley by
16 * William Jolitz and Don Ahn.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 * must display the following acknowledgement:
28 * This product includes software developed by
29 * Hellmuth Michaelis, Brian Dunford-Shore, Joerg Wunsch, Scott Turner
30 * and Charles Hannum.
31 * 4. The name authors may not be used to endorse or promote products
32 * derived from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
35 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
37 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
39 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
40 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
41 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 */
45
46/*---------------------------------------------------------------------------*
47 *
48 * pcvt_drv.c VT220 Driver Main Module / OS - Interface
49 * ---------------------------------------------------------
50 *
51 * Last Edit-Date: [Mon Dec 27 14:03:36 1999]
52 *
53 * $FreeBSD: src/sys/i386/isa/pcvt/pcvt_drv.c,v 1.63.2.1 2001/02/26 04:23:13 jlemon Exp $
7b95be2a 54 * $DragonFly: src/sys/dev/video/pcvt/i386/Attic/pcvt_drv.c,v 1.5 2003/07/21 07:57:45 dillon Exp $
984263bc
MD
55 *
56 *---------------------------------------------------------------------------*/
57
58#include "vt.h"
59#if NVT > 0
60
61#define EXTERN /* allocate mem */
62
63#include <i386/isa/pcvt/pcvt_hdr.h> /* global include */
64
65#if PCVT_FREEBSD >= 200
66#include <sys/bus.h>
67#include <machine/stdarg.h>
68#else
69#include "machine/stdarg.h"
70#endif
71
72extern int getchar __P((void));
73
74#if PCVT_NETBSD
75 extern u_short *Crtat;
76#endif /* PCVT_NETBSD */
77
78static void vgapelinit(void); /* read initial VGA DAC palette */
79
80#if defined XSERVER && !PCVT_USL_VT_COMPAT
7b95be2a 81static int pcvt_xmode_set(int on, struct thread *td); /* initialize for X mode */
984263bc
MD
82#endif /* XSERVER && !PCVT_USL_VT_COMPAT */
83
84#ifdef _DEV_KBD_KBDREG_H_
85static void detect_kbd(void *arg);
86static kbd_callback_func_t pcevent;
87#endif
88
89static cn_probe_t pccnprobe;
90static cn_init_t pccninit;
91static cn_term_t pccnterm;
92static cn_getc_t pccngetc;
93static cn_checkc_t pccncheckc;
94static cn_putc_t pccnputc;
95
96CONS_DRIVER(pc, pccnprobe, pccninit, pccnterm, pccngetc, pccncheckc, pccnputc,
97 NULL);
98
99static d_open_t pcopen;
100static d_close_t pcclose;
101static d_ioctl_t pcioctl;
102static d_mmap_t pcmmap;
103
104#define CDEV_MAJOR 12
105static struct cdevsw pc_cdevsw = {
fabb8ceb
MD
106 /* name */ "vt",
107 /* maj */ CDEV_MAJOR,
108 /* flags */ D_TTY | D_KQFILTER,
109 /* port */ NULL,
110 /* autoq */ 0,
111
984263bc
MD
112 /* open */ pcopen,
113 /* close */ pcclose,
114 /* read */ ttyread,
115 /* write */ ttywrite,
116 /* ioctl */ pcioctl,
117 /* poll */ ttypoll,
118 /* mmap */ pcmmap,
119 /* strategy */ nostrategy,
984263bc
MD
120 /* dump */ nodump,
121 /* psize */ nopsize,
fabb8ceb 122 /* kqfilter */ ttykqfilter
984263bc
MD
123};
124
125#if PCVT_NETBSD > 100 /* NetBSD-current Feb 20 1995 */
126int
127pcprobe(struct device *parent, void *match, void *aux)
128#else
129#if PCVT_NETBSD > 9
130int
131pcprobe(struct device *parent, struct device *self, void *aux)
132#else
133int
134pcprobe(struct isa_device *dev)
135#endif /* PCVT_NETBSD > 9 */
136#endif /* PCVT_NETBSD > 100 */
137{
138#ifdef _DEV_KBD_KBDREG_H_
139 int i;
140
141 if (kbd == NULL) {
142 reset_keyboard = 0;
143 kbd_configure(KB_CONF_PROBE_ONLY);
144 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)dev->id_unit);
145 if ((i < 0) || ((kbd = kbd_get_keyboard(i)) == NULL))
146 return (-1);
147 }
148 reset_keyboard = 1; /* it's now safe to do kbd reset */
149#endif /* _DEV_KBD_KBDREG_H_ */
150
151 kbd_code_init();
152
153#if PCVT_NETBSD > 9
154 ((struct isa_attach_args *)aux)->ia_iosize = 16;
155 return 1;
156#else
157#ifdef _DEV_KBD_KBDREG_H_
158 return (-1);
159#elif PCVT_NETBSD || PCVT_FREEBSD
160 return (16);
161#else
162 return 1;
163#endif /* PCVT_NETBSD || PCVT_FREEBSD */
164#endif /* PCVT_NETBSD > 9 */
165
166}
167
168#if PCVT_NETBSD > 9
169void
170pcattach(struct device *parent, struct device *self, void *aux)
171{
172 struct isa_attach_args *ia = aux;
173 static struct intrhand vthand;
174#else
175int
176pcattach(struct isa_device *dev)
177{
178#endif /* PCVT_NETBSD > 9 */
179
180 int i;
181
182 vt_coldmalloc(); /* allocate memory for screens */
183
184#ifdef _DEV_KBD_KBDREG_H_
185 if (kbd == NULL)
186 timeout(detect_kbd, (void *)dev->id_unit, hz*2);
187#endif /* _DEV_KBD_KBDREG_H_ */
188
189#if PCVT_NETBSD || PCVT_FREEBSD
190
191#if PCVT_NETBSD > 9
192 printf(": ");
193#else
194 printf("vt%d: ", dev->id_unit);
195#endif /* PCVT_NETBSD > 9 */
196
197 switch(adaptor_type)
198 {
199 case MDA_ADAPTOR:
200 printf("mda");
201 break;
202
203 case CGA_ADAPTOR:
204 printf("cga");
205 break;
206
207 case EGA_ADAPTOR:
208 printf("ega");
209 break;
210
211 case VGA_ADAPTOR:
212 printf("%s, ", (char *)vga_string(vga_type));
213 if(can_do_132col)
214 printf("80/132 col");
215 else
216 printf("80 col");
217 vgapelinit();
218 break;
219
220 default:
221 printf("unknown");
222 break;
223 }
224
225 if(color == 0)
226 printf(", mono");
227 else
228 printf(", color");
229
230 printf(", %d scr, ", totalscreens);
231
232 switch(keyboard_type)
233 {
234 case KB_AT:
235 printf("at-");
236 break;
237
238 case KB_MFII:
239 printf("mf2-");
240 break;
241
242 default:
243 printf("unknown ");
244 break;
245 }
246
247 printf("kbd, [R%s]\n", PCVT_REL);
248
249#if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
250
251 for(i = 0; i < totalscreens; i++)
252 {
253
254#if PCVT_NETBSD
255 pc_tty[i] = ttymalloc();
256 vs[i].vs_tty = pc_tty[i];
257#else /* !PCVT_NETBSD */
258 pccons[i] = ttymalloc(pccons[i]);
259 vs[i].vs_tty = pccons[i];
260#endif /* PCVT_NETBSD */
261
262 }
263
264#if PCVT_EMU_MOUSE
265#if PCVT_NETBSD
266 pc_tty[totalscreens] = ttymalloc(); /* the mouse emulator tty */
267#else /* !PCVT_NETBSD */
268 /* the mouse emulator tty */
269 pc_tty[totalscreens] = ttymalloc(pccons[totalscreens]);
270#endif /* PCVT_NETBSD */
271#endif /* PCVT_EMU_MOUSE */
272
273#if PCVT_NETBSD
274 pcconsp = pc_tty[0];
275#else /* !PCVT_NETBSD */
276 pcconsp = pccons[0];
277#endif /* PCVT_NETBSD */
278
279#endif /* #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
280
281#else /* !PCVT_NETBSD && !PCVT_FREEBSD*/
282
283 switch(adaptor_type)
284 {
285 case MDA_ADAPTOR:
286 printf(" <mda");
287 break;
288
289 case CGA_ADAPTOR:
290 printf(" <cga");
291 break;
292
293 case EGA_ADAPTOR:
294 printf(" <ega");
295 break;
296
297 case VGA_ADAPTOR:
298 printf(" <%s,", (char *)vga_string(vga_type));
299 if(can_do_132col)
300 printf("80/132 col");
301 else
302 printf("80 col");
303 vgapelinit();
304 break;
305
306 default:
307 printf(" <unknown");
308 break;
309 }
310
311 if(color == 0)
312 printf(",mono");
313 else
314 printf(",color");
315
316 printf(",%d scr,", totalscreens);
317
318 switch(keyboard_type)
319 {
320 case KB_AT:
321 printf("at-");
322 break;
323
324 case KB_MFII:
325 printf("mf2-");
326 break;
327
328 default:
329 printf("unknown ");
330 break;
331 }
332
333 printf("kbd,[R%s]>", PCVT_REL);
334
335#endif /* PCVT_NETBSD || PCVT_FREEBSD */
336
337#if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
338 for(i = 0; i < totalscreens; i++)
339 {
340 ttyregister(&pccons[i]);
341 vs[i].vs_tty = &pccons[i];
342 make_dev(&pc_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
343 }
344#endif /* !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
345
346 async_update(UPDATE_START); /* start asynchronous updates */
347
348#if PCVT_NETBSD > 9
349
350 vthand.ih_fun = pcrint;
351 vthand.ih_arg = 0;
352 vthand.ih_level = IPL_TTY;
353
354#if (PCVT_NETBSD > 100) && defined(IST_EDGE)
355 intr_establish(ia->ia_irq, IST_EDGE, &vthand);
356#else /* PCVT_NETBSD > 100 */
357 intr_establish(ia->ia_irq, &vthand);
358#endif /* PCVT_NETBSD > 100 */
359
360#else /* PCVT_NETBSD > 9 */
361
362 dev->id_ointr = pcrint;
363
364 return 1;
365
366#endif /* PCVT_NETBSD > 9 */
367
368}
369
370/* had a look at the friedl driver */
371
372#if !PCVT_NETBSD
373
374struct tty *
375get_pccons(Dev_t dev)
376{
377 register int i = minor(dev);
378
379#if PCVT_EMU_MOUSE
380 if(i == totalscreens)
381#if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
382 return(&pccons[i]);
383#else
384 return(pccons[i]);
385#endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
386#endif /* PCVT_EMU_MOUSE */
387
388 if(i >= PCVT_NSCREENS)
389 return(NULL);
390#if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
391 return(&pccons[i]);
392#else
393 return(pccons[i]);
394#endif
395}
396
397#else
398
399struct tty *
400get_pccons(Dev_t dev)
401{
402 register int i = minor(dev);
403
404#if PCVT_EMU_MOUSE
405 if(i == totalscreens)
406 return(pc_tty[i]);
407#endif /* PCVT_EMU_MOUSE */
408
409 if(i >= PCVT_NSCREENS)
410 return(NULL);
411 return(pc_tty[i]);
412}
413
414#endif /* !PCVT_NETBSD */
415
416/*---------------------------------------------------------------------------*
417 * /dev/ttyc0, /dev/ttyc1, etc.
418 *---------------------------------------------------------------------------*/
419int
7b95be2a 420pcopen(Dev_t dev, int flag, int mode, struct thread *td)
984263bc
MD
421{
422 register struct tty *tp;
423 register struct video_state *vsx;
424 int s, retval;
425 int winsz = 0;
426 int i = minor(dev);
427
428#if PCVT_EMU_MOUSE
429 if(i == totalscreens)
430 vsx = 0;
431 else
432#endif /* PCVT_EMU_MOUSE */
433
434 vsx = &vs[i];
435
436 if((tp = get_pccons(dev)) == NULL)
437 return ENXIO;
438
439 dev->si_tty = tp;
440
441#if PCVT_EMU_MOUSE
442 if(i == totalscreens)
443 {
444 if(mouse.opened == 0)
445 mouse.buttons = mouse.extendedseen =
446 mouse.breakseen = mouse.lastmove.tv_sec = 0;
447 mouse.minor = i;
448 mouse.opened++;
449 }
450 else
451#endif /* PCVT_EMU_MOUSE */
452
453 vsx->openf++;
454
455 tp->t_oproc = pcstart;
456 tp->t_param = pcparam;
457 tp->t_stop = nottystop;
458 tp->t_dev = dev;
459
460 if ((tp->t_state & TS_ISOPEN) == 0)
461 {
462
463#ifdef TS_WOPEN /* not (FreeBSD-1.1.5 or FreeBSD some time after 2.0.5) */
464 tp->t_state |= TS_WOPEN;
465#endif
466
467 ttychars(tp);
468 tp->t_iflag = TTYDEF_IFLAG;
469 tp->t_oflag = TTYDEF_OFLAG;
470 tp->t_cflag = TTYDEF_CFLAG;
471 tp->t_lflag = TTYDEF_LFLAG;
472 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
473 pcparam(tp, &tp->t_termios);
474 (*linesw[tp->t_line].l_modem)(tp, 1); /* fake connection */
475 winsz = 1; /* set winsize later */
476 }
dadab5e9 477 else if (tp->t_state & TS_XCLUDE && suser(td))
984263bc
MD
478 return (EBUSY);
479
480#if PCVT_NETBSD || (PCVT_FREEBSD >= 200)
481 retval = ((*linesw[tp->t_line].l_open)(dev, tp));
482#else
483 retval = ((*linesw[tp->t_line].l_open)(dev, tp, flag));
484#endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */
485
486 if(winsz == 1)
487 {
488
489 /*
490 * The line discipline has clobbered t_winsize if TS_ISOPEN
491 * was clear. (NetBSD PR #400 from Bill Sommerfeld)
492 * We have to do this after calling the open routine, because
493 * it does some other things in other/older *BSD releases -hm
494 */
495
496 s = spltty();
497
498 tp->t_winsize.ws_col = vsx->maxcol;
499 tp->t_winsize.ws_row = vsx->screen_rows;
500 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
501 tp->t_winsize.ws_ypixel = 400;
502
503 splx(s);
504 }
505
506 return(retval);
507}
508
509int
7b95be2a 510pcclose(Dev_t dev, int flag, int mode, struct thread *td)
984263bc
MD
511{
512 register struct tty *tp;
513 register struct video_state *vsx;
514 int i = minor(dev);
515
516#if PCVT_EMU_MOUSE
517 if(i == totalscreens)
518 vsx = 0;
519 else
520#endif /* PCVT_EMU_MOUSE */
521
522 vsx = &vs[i];
523
524 if((tp = get_pccons(dev)) == NULL)
525 return ENXIO;
526
527 (*linesw[tp->t_line].l_close)(tp, flag);
528 ttyclose(tp);
529
530#if PCVT_EMU_MOUSE
531 if(i == totalscreens)
532 mouse.opened = 0;
533 else
534#endif /* PCVT_EMU_MOUSE */
535
536 vsx->openf = 0;
537
538#if PCVT_USL_VT_COMPAT
539#if PCVT_EMU_MOUSE
540
541 if(i == totalscreens)
542 return (0);
543
544#endif /* PCVT_EMU_MOUSE */
545
546 reset_usl_modes(vsx);
547
548#endif /* PCVT_USL_VT_COMPAT */
549
550 return(0);
551}
552
553int
7b95be2a 554pcioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
984263bc
MD
555{
556 register int error;
557 register struct tty *tp;
558
559 if((tp = get_pccons(dev)) == NULL)
560 return(ENXIO);
561
562 /* note that some ioctl's are global, e.g. KBSTPMAT: There is
563 * only one keyboard and different repeat rates for instance between
564 * sessions are a suspicious wish. If you really need this make the
565 * appropriate variables arrays
566 */
567
568#if PCVT_EMU_MOUSE
569 if(minor(dev) == totalscreens)
570 {
571 if((error = mouse_ioctl(dev, cmd, data)) >= 0)
572 return error;
573 goto do_standard;
574 }
575#endif /* PCVT_EMU_MOUSE */
576
577#ifdef XSERVER
578#if PCVT_USL_VT_COMPAT
579
7b95be2a 580 if((error = usl_vt_ioctl(dev, cmd, data, flag, td->td_proc)) >= 0)
984263bc
MD
581 return error;
582
583 /*
584 * just for compatibility:
585 * XFree86 < 2.0 and SuperProbe still might use it
586 *
587 * NB: THIS IS A HACK! Do not use it unless you explicitly need.
588 * Especially, since the vty is not put into process-controlled
589 * mode (this would require the application to co-operate), any
590 * attempts to switch vtys while this kind of X mode is active
591 * may cause serious trouble.
592 */
593 switch(cmd)
594 {
595 case CONSOLE_X_MODE_ON:
596 {
597 int i;
598
7b95be2a 599 if((error = usl_vt_ioctl(dev, KDENABIO, 0, flag, td->td_proc)) > 0)
984263bc
MD
600 return error;
601
602 i = KD_GRAPHICS;
7b95be2a 603 if((error = usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, td->td_proc))
984263bc
MD
604 > 0)
605 return error;
606
607 i = K_RAW;
7b95be2a 608 error = usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, td->td_proc);
984263bc
MD
609 return error;
610 }
611
612 case CONSOLE_X_MODE_OFF:
613 {
614 int i;
615
7b95be2a 616 (void)usl_vt_ioctl(dev, KDDISABIO, 0, flag, td->td_proc);
984263bc
MD
617
618 i = KD_TEXT;
7b95be2a 619 (void)usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, td->td_proc);
984263bc
MD
620
621 i = K_XLATE;
7b95be2a 622 (void)usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, td->td_proc);
984263bc
MD
623 return 0;
624 }
625
626
627 case CONSOLE_X_BELL:
628
629 /*
630 * If `data' is non-null, the first int value denotes
631 * the pitch, the second a duration. Otherwise, behaves
632 * like BEL.
633 */
634
635 if (data)
636 {
637
638#if PCVT_NETBSD
639 sysbeep(((int *)data)[0],
640 ((int *)data)[1] * hz / 1000);
641#else /* PCVT_NETBSD */
642 sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
643 ((int *)data)[1] * hz / 3000);
644#endif /* PCVT_NETBSD */
645
646 }
647 else
648 {
649 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
650 }
651 return (0);
652
653 default: /* fall through */ ;
654 }
655
656#else /* PCVT_USL_VT_COMPAT */
657
658 switch(cmd)
659 {
660 case CONSOLE_X_MODE_ON:
7b95be2a 661 return pcvt_xmode_set(1, td->td_proc);
984263bc
MD
662
663 case CONSOLE_X_MODE_OFF:
7b95be2a 664 return pcvt_xmode_set(0, td->td_proc);
984263bc
MD
665
666 case CONSOLE_X_BELL:
667
668 /*
669 * If `data' is non-null, the first int value denotes
670 * the pitch, the second a duration. Otherwise, behaves
671 * like BEL.
672 */
673
674 if (data)
675 {
676
677#if PCVT_NETBSD
678 sysbeep(((int *)data)[0],
679 ((int *)data)[1] * hz / 1000);
680#else /* PCVT_NETBSD */
681 sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
682 ((int *)data)[1] * hz / 3000);
683#endif /* PCVT_NETBSD */
684
685 }
686 else
687 {
688 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
689 }
690 return (0);
691
692 default: /* fall through */ ;
693 }
694
695#endif /* PCVT_USL_VT_COMPAT */
696#endif /* XSERVER */
697
698 if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
699 return error;
700
701 if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
702 return error;
703
704#if PCVT_EMU_MOUSE
705do_standard:
706#endif
707
708#if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
7b95be2a 709 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td))
984263bc
MD
710 != ENOIOCTL)
711 return (error);
712#else
713 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag)) >= 0)
714 return(error);
715#endif /* PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 */
716
717#if PCVT_NETBSD > 9
7b95be2a 718 if((error = ttioctl(tp, cmd, data, flag, td)) >= 0)
984263bc
MD
719 return (error);
720#else
721 if((error = ttioctl(tp, cmd, data, flag)) != ENOIOCTL)
722 return (error);
723#endif /* PCVT_NETBSD > 9 */
724
725 return (ENOTTY);
726}
727
728int
729pcmmap(Dev_t dev, vm_offset_t offset, int nprot)
730{
731 if (offset > 0x20000 - PAGE_SIZE)
732 return -1;
733 return i386_btop((0xa0000 + offset));
734}
735
736/*---------------------------------------------------------------------------*
737 *
738 * handle a keyboard receive interrupt
739 *
740 * NOTE: the keyboard is multiplexed by means of "pcconsp"
741 * between virtual screens. pcconsp - switching is done in
742 * the vgapage() routine
743 *
744 *---------------------------------------------------------------------------*/
745
746#if PCVT_KBD_FIFO
747
748u_char pcvt_kbd_fifo[PCVT_KBD_FIFO_SZ];
749static int pcvt_kbd_wptr = 0;
750int pcvt_kbd_rptr = 0;
751short pcvt_kbd_count= 0;
752static u_char pcvt_timeout_scheduled = 0;
753
754static void
755pcvt_timeout(void *arg)
756{
757 u_char *cp;
758
759#if PCVT_SLOW_INTERRUPT
760 int s;
761#endif
762
763 pcvt_timeout_scheduled = 0;
764
765#if PCVT_SCREENSAVER
766 pcvt_scrnsv_reset();
767#endif /* PCVT_SCREENSAVER */
768
769 while (pcvt_kbd_count)
770 {
771 if (((cp = sgetc(1)) != 0) &&
772 (vs[current_video_screen].openf))
773 {
774
775#if PCVT_NULLCHARS
776 if(*cp == '\0')
777 {
778 /* pass a NULL character */
779 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
780 }
781/* XXX */ else
782#endif /* PCVT_NULLCHARS */
783
784 while (*cp)
785 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
786 }
787
788 PCVT_DISABLE_INTR ();
789
790 if (!pcvt_kbd_count)
791 pcvt_timeout_scheduled = 0;
792
793 PCVT_ENABLE_INTR ();
794 }
795
796 return;
797}
798#endif
799
800#ifdef _DEV_KBD_KBDREG_H_
801static void
802detect_kbd(void *arg)
803{
804 int unit = (int)arg;
805 int i;
806
807 if (kbd != NULL)
808 return;
809 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
810 if (i >= 0)
811 kbd = kbd_get_keyboard(i);
812 if (kbd != NULL)
813 {
814 reset_keyboard = 1; /* ok to reset the keyboard */
815 kbd_code_init();
816 return;
817 }
818 reset_keyboard = 0;
819 timeout(detect_kbd, (void *)unit, hz*2);
820}
821
822int
823pcevent(keyboard_t *thiskbd, int event, void *arg)
824{
825 int unit = (int)arg;
826
827 if (thiskbd != kbd)
828 return EINVAL; /* shouldn't happen */
829
830 switch (event) {
831 case KBDIO_KEYINPUT:
832 pcrint(unit);
833 return 0;
834 case KBDIO_UNLOADING:
835 reset_keyboard = 0;
836 kbd = NULL;
837 kbd_release(thiskbd, (void *)&kbd);
838 timeout(detect_kbd, (void *)unit, hz*4);
839 return 0;
840 default:
841 return EINVAL;
842 }
843}
844#endif /* _DEV_KBD_KBDREG_H_ */
845
846void
847pcrint(int unit)
848{
849
850#if PCVT_KBD_FIFO
851 u_char dt;
852 u_char ret = -1;
853
854# if PCVT_SLOW_INTERRUPT
855 int s;
856# endif
857
858# ifdef _DEV_KBD_KBDREG_H_
859 int c;
860# endif
861
862#else /* !PCVT_KBD_FIFO */
863 u_char *cp;
864#endif /* PCVT_KBD_FIFO */
865
866#if PCVT_SCREENSAVER
867 pcvt_scrnsv_reset();
868#endif /* PCVT_SCREENSAVER */
869
870#if PCVT_KBD_FIFO
871 if (kbd_polling)
872 {
873 sgetc(1);
874 return;
875 }
876
877# ifndef _DEV_KBD_KBDREG_H_
878 while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) /* check 8042 buffer */
879 {
880 ret = 1; /* got something */
881
882 PCVT_KBD_DELAY(); /* 7 us delay */
883
884 dt = inb(CONTROLLER_DATA); /* get it 8042 data */
885# else
886 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
887 {
888 ret = 1; /* got something */
889 dt = c;
890# endif /* _DEV_KBD_KBDREG_H_ */
891
892 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
893 {
894 log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
895 }
896 else
897 {
898 pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
899
900 PCVT_DISABLE_INTR (); /* XXX necessary ? */
901 pcvt_kbd_count++; /* update fifo count */
902 PCVT_ENABLE_INTR ();
903
904 if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
905 pcvt_kbd_wptr = 0; /* wraparound pointer */
906 }
907 }
908
909 if (ret == 1) /* got data from keyboard ? */
910 {
911 if (!pcvt_timeout_scheduled) /* if not already active .. */
912 {
913 PCVT_DISABLE_INTR ();
914 pcvt_timeout_scheduled = 1; /* flag active */
915 timeout(pcvt_timeout, NULL, hz / 100); /* fire off */
916 PCVT_ENABLE_INTR ();
917 }
918 }
919
920#else /* !PCVT_KBD_FIFO */
921
922 if((cp = sgetc(1)) == 0)
923 return;
924
925 if (kbd_polling)
926 return;
927
928 if(!(vs[current_video_screen].openf)) /* XXX was vs[minor(dev)] */
929 return;
930
931#if PCVT_NULLCHARS
932 if(*cp == '\0')
933 {
934 /* pass a NULL character */
935 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
936 return;
937 }
938#endif /* PCVT_NULLCHARS */
939
940 while (*cp)
941 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
942
943#endif /* PCVT_KBD_FIFO */
944}
945
946
947#if PCVT_NETBSD || PCVT_FREEBSD >= 200
948
949void
950pcstart(register struct tty *tp)
951{
952 register struct clist *rbp;
953 int s, len;
954 u_char buf[PCVT_PCBURST];
955
956 s = spltty();
957
958 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
959 goto out;
960
961 tp->t_state |= TS_BUSY;
962
963 splx(s);
964
965 async_update(UPDATE_KERN);
966
967 rbp = &tp->t_outq;
968
969 /*
970 * Call q_to_b() at spltty() to ensure that the queue is empty when
971 * the loop terminates.
972 */
973
974 s = spltty();
975
976 while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
977 {
978 if(vs[minor(tp->t_dev)].scrolling)
979 sgetc(31337);
980
981 /*
982 * We need to do this outside spl since it could be fairly
983 * expensive and we don't want our serial ports to overflow.
984 */
985 splx(s);
986 sput(&buf[0], 0, len, minor(tp->t_dev));
987 s = spltty();
988 }
989
990 tp->t_state &= ~TS_BUSY;
991
992#ifndef TS_ASLEEP /* FreeBSD some time after 2.0.5 */
993 ttwwakeup(tp);
994#else
995 if (rbp->c_cc <= tp->t_lowat)
996 {
997 if (tp->t_state&TS_ASLEEP)
998 {
999 tp->t_state &= ~TS_ASLEEP;
1000 wakeup((caddr_t)rbp);
1001 }
1002 selwakeup(&tp->t_wsel);
1003 }
1004#endif
1005out:
1006 splx(s);
1007}
1008
1009void
1010pcstop(struct tty *tp, int flag)
1011{
1012}
1013
1014#else /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1015
1016void
1017pcstart(struct tty *tp)
1018{
1019 int s;
1020 unsigned char c;
1021
1022 s = spltty();
1023
1024 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
1025 {
1026 goto out;
1027 }
1028
1029 for(;;)
1030 {
1031
1032#if !(PCVT_FREEBSD > 114)
1033
1034#if !(PCVT_FREEBSD > 111)
1035 if (RB_LEN(&tp->t_out) <= tp->t_lowat)
1036#else
1037 if (RB_LEN(tp->t_out) <= tp->t_lowat)
1038#endif
1039 {
1040 if (tp->t_state&TS_ASLEEP)
1041 {
1042 tp->t_state &= ~TS_ASLEEP;
1043#if !(PCVT_FREEBSD > 111)
1044 wakeup((caddr_t)&tp->t_out);
1045#else
1046 wakeup((caddr_t)tp->t_out);
1047#endif
1048 }
1049
1050 if (tp->t_wsel)
1051 {
1052 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
1053 tp->t_wsel = 0;
1054 tp->t_state &= ~TS_WCOLL;
1055 }
1056 }
1057
1058#else /* PCVT_FREEBSD > 114 */
1059 if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT)
1060 || tp->t_wsel) {
1061 ttwwakeup(tp);
1062 }
1063#endif /* !PCVT_FREEBSD > 114 */
1064
1065#if !(PCVT_FREEBSD > 111)
1066 if (RB_LEN(&tp->t_out) == 0)
1067#else
1068 if (RB_LEN(tp->t_out) == 0)
1069#endif
1070 {
1071 goto out;
1072 }
1073
1074#if !(PCVT_FREEBSD > 111)
1075 c = getc(&tp->t_out);
1076#else
1077 c = getc(tp->t_out);
1078#endif
1079
1080 tp->t_state |= TS_BUSY; /* patch from Frank Maclachlan */
1081 splx(s);
1082 sput(&c, 0, 1, minor(tp->t_dev));
1083 spltty();
1084 tp->t_state &= ~TS_BUSY; /* patch from Frank Maclachlan */
1085 }
1086out:
1087 splx(s);
1088}
1089
1090#endif /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1091
1092/*---------------------------------------------------------------------------*
1093 * /dev/console
1094 *---------------------------------------------------------------------------*/
1095
1096#if !PCVT_NETBSD /* has moved to cons.c in netbsd-current */
1097void
1098consinit() /* init for kernel messages during boot */
1099{
1100}
1101#endif /* PCVT_NETBSD */
1102
1103#if PCVT_FREEBSD > 205
1104static void
1105#else
1106int
1107#endif
1108pccnprobe(struct consdev *cp)
1109{
1110 int unit = 0;
1111 int i;
1112
1113 /* See if this driver is disabled in probe hint. */
1114 if (resource_int_value("vt", unit, "disabled", &i) == 0 && i) {
1115 cp->cn_pri = CN_DEAD;
1116 return;
1117 }
1118
1119#ifdef _DEV_KBD_KBDREG_H_
1120 kbd_configure(KB_CONF_PROBE_ONLY);
1121 if (kbd_find_keyboard("*", unit) < 0)
1122 {
1123 cp->cn_pri = CN_DEAD;
1124 return;
1125 }
1126#endif /* _DEV_KBD_KBDREG_H_ */
1127
1128 /* initialize required fields */
1129
1130 cp->cn_dev = makedev(CDEV_MAJOR, 0);
1131 cp->cn_pri = CN_INTERNAL;
1132
1133#if !PCVT_NETBSD
1134
1135#if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
1136 cp->cn_tp = &pccons[0];
1137#else
1138 cp->cn_tp = pccons[0];
1139#endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
1140
1141#endif /* !PCVT_NETBSD */
1142
1143#if PCVT_FREEBSD <= 205
1144 return 1;
1145#endif
1146}
1147
1148#if PCVT_FREEBSD > 205
1149static void
1150#else
1151int
1152#endif
1153pccninit(struct consdev *cp)
1154{
1155 int unit = 0;
1156 int i;
1157
1158 pcvt_is_console = 1;
1159
1160#ifdef _DEV_KBD_KBDREG_H_
1161 /*
1162 * Don't reset the keyboard via `kbdio' just yet.
1163 * The system clock has not been calibrated...
1164 */
1165 reset_keyboard = 0;
1166
1167 if (kbd)
1168 {
1169 kbd_release(kbd, (void *)&kbd);
1170 kbd = NULL;
1171 }
1172 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
1173 if (i >= 0)
1174 kbd = kbd_get_keyboard(i);
1175
1176#if PCVT_SCANSET == 2
1177 /*
1178 * Turn off scancode translation early so that UserConfig
1179 * and DDB can read the keyboard.
1180 */
1181 if (kbd)
1182 {
1183 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
1184 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1185 KBD_TRANSLATION, 0);
1186 }
1187#endif /* PCVT_SCANSET == 2 */
1188
1189#endif /* _DEV_KBD_KBDREG_H_ */
1190
1191#if PCVT_FREEBSD <= 205
1192 return 0;
1193#endif
1194}
1195
1196static void
1197pccnterm(struct consdev *cp)
1198{
1199#ifdef _DEV_KBD_KBDREG_H_
1200 if (kbd)
1201 {
1202 kbd_release(kbd, (void *)&kbd);
1203 kbd = NULL;
1204 }
1205#endif /* _DEV_KBD_KBDREG_H_ */
1206}
1207
1208#if PCVT_FREEBSD > 205
1209static void
1210#else
1211int
1212#endif
1213pccnputc(Dev_t dev, U_char c)
1214{
1215
1216#if PCVT_SW0CNOUTP
1217
1218 if(current_video_screen != 0)
1219 {
1220
1221#if !PCVT_USL_VT_COMPAT
1222 vgapage(0);
1223#else
1224 switch_screen(0, 0);
1225#endif /* !PCVT_USL_VT_COMPAT */
1226
1227 }
1228
1229#endif /* PCVT_SW0CNOUTP */
1230
1231 if (c == '\n')
1232 sput("\r", 1, 1, 0);
1233
1234 sput((char *) &c, 1, 1, 0);
1235
1236 async_update(UPDATE_KERN);
1237
1238#if PCVT_FREEBSD <= 205
1239 return 0;
1240#endif
1241}
1242
1243static int
1244pccngetc(Dev_t dev)
1245{
1246 register int s;
1247 static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
1248 register u_char c;
1249
1250#ifdef XSERVER
1251
1252#if !PCVT_USL_VT_COMPAT
1253 if (pcvt_xmode)
1254 return 0;
1255#else /* !PCVT_USL_VT_COMPAT */
1256 if (pcvt_kbd_raw)
1257 return 0;
1258#endif /* !PCVT_USL_VT_COMPAT */
1259
1260#endif /* XSERVER */
1261
1262 if (cp && *cp)
1263 /*
1264 * We still have a pending key sequence, e.g.
1265 * from an arrow key. Deliver this one first.
1266 */
1267 return (*cp++);
1268
1269#ifdef _DEV_KBD_KBDREG_H_
1270 if (kbd == NULL)
1271 return 0;
1272#endif
1273
1274 s = spltty(); /* block pcrint while we poll */
1275 kbd_polling = 1;
1276#ifdef _DEV_KBD_KBDREG_H_
1277 (*kbdsw[kbd->kb_index]->enable)(kbd);
1278#endif
1279 cp = sgetc(0);
1280#ifdef _DEV_KBD_KBDREG_H_
1281 (*kbdsw[kbd->kb_index]->disable)(kbd);
1282#endif
1283 kbd_polling = 0;
1284 splx(s);
1285 c = *cp++;
1286 if (c && *cp) {
1287 /* Preserve the multi-char sequence for the next call. */
1288 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
1289 cp = cbuf;
1290 } else
1291 cp = 0;
1292
1293#if ! (PCVT_FREEBSD >= 201)
1294 /* this belongs to cons.c */
1295 if (c == '\r')
1296 c = '\n';
1297#endif /* ! (PCVT_FREEBSD >= 201) */
1298
1299 return c;
1300}
1301
1302#if PCVT_FREEBSD >= 200
1303static int
1304pccncheckc(Dev_t dev)
1305{
1306 char *cp;
1307 int x;
1308
1309#ifdef _DEV_KBD_KBDREG_H_
1310 if (kbd == NULL)
1311 return 0;
1312#endif
1313
1314 x = spltty();
1315 kbd_polling = 1;
1316#ifdef _DEV_KBD_KBDREG_H_
1317 (*kbdsw[kbd->kb_index]->enable)(kbd);
1318#endif
1319 cp = sgetc(1);
1320#ifdef _DEV_KBD_KBDREG_H_
1321 (*kbdsw[kbd->kb_index]->disable)(kbd);
1322#endif
1323 kbd_polling = 0;
1324 splx(x);
1325 return (cp == NULL ? -1 : *cp);
1326}
1327#endif /* PCVT_FREEBSD >= 200 */
1328
1329#if PCVT_NETBSD >= 100
1330void
1331pccnpollc(Dev_t dev, int on)
1332{
1333 kbd_polling = on;
1334 if (!on) {
1335 register int s;
1336
1337 /*
1338 * If disabling polling, make sure there are no bytes left in
1339 * the FIFO, holding up the interrupt line. Otherwise we
1340 * won't get any further interrupts.
1341 */
1342 s = spltty();
1343 pcrint();
1344 splx(s);
1345 }
1346}
1347#endif /* PCVT_NETBSD >= 100 */
1348
1349/*---------------------------------------------------------------------------*
1350 * Set line parameters
1351 *---------------------------------------------------------------------------*/
1352int
1353pcparam(struct tty *tp, struct termios *t)
1354{
1355 register int cflag = t->c_cflag;
1356
1357 /* and copy to tty */
1358
1359 tp->t_ispeed = t->c_ispeed;
1360 tp->t_ospeed = t->c_ospeed;
1361 tp->t_cflag = cflag;
1362
1363 return(0);
1364}
1365
1366/*----------------------------------------------------------------------*
1367 * read initial VGA palette (as stored by VGA ROM BIOS) into
1368 * palette save area
1369 *----------------------------------------------------------------------*/
1370void
1371vgapelinit(void)
1372{
1373 register unsigned idx;
1374 register struct rgb *val;
1375
1376 /* first, read all and store to first screen's save buffer */
1377 for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
1378 vgapaletteio(idx, val, 0 /* read it */);
1379
1380 /* now, duplicate for remaining screens */
1381 for(idx = 1; idx < PCVT_NSCREENS; idx++)
1382 bcopy(vs[0].palette, vs[idx].palette,
1383 NVGAPEL * sizeof(struct rgb));
1384}
1385
1386#if defined XSERVER && !PCVT_USL_VT_COMPAT
1387/*----------------------------------------------------------------------*
1388 * initialize for X mode
1389 * i.e.: grant current process (the X server) all IO privileges,
1390 * and mark in static variable so other hooks can test for it,
1391 * save all loaded fonts and screen pages to pageable buffers;
1392 * if parameter `on' is false, the same procedure is done reverse.
1393 *----------------------------------------------------------------------*/
1394static int
7b95be2a 1395pcvt_xmode_set(int on, struct thread *td)
984263bc
MD
1396{
1397 static unsigned char *saved_fonts[NVGAFONTS];
1398
1399#if PCVT_SCREENSAVER
1400 static unsigned saved_scrnsv_tmo = 0;
1401#endif /* PCVT_SCREENSAVER */
1402
1403#if (PCVT_NETBSD > 9) || (PCVT_FREEBSD > 102)
1404 struct trapframe *fp;
1405#else
1406 struct syscframe *fp;
1407#endif /* PCVT_NETBSD > 9 */
1408
1409 int error, i;
1410
1411 /* X will only run on VGA and Hercules adaptors */
1412
1413 if(adaptor_type != VGA_ADAPTOR && adaptor_type != MDA_ADAPTOR)
1414 return (EINVAL);
1415
1416#if PCVT_NETBSD > 9
1417 fp = (struct trapframe *)p->p_regs;
1418#else
1419 fp = (struct syscframe *)p->p_regs;
1420#endif /* PCVT_NETBSD > 9 */
1421
1422 if(on)
1423 {
1424 /*
1425 * Test whether the calling process has super-user privileges
1426 * and we're in insecure mode.
1427 * This prevents us from granting the potential security hole
1428 * `IO priv' to insufficiently privileged processes.
1429 */
dadab5e9 1430 error = suser(td);
984263bc
MD
1431 if (error != 0)
1432 return (error);
1433 if (securelevel > 0)
1434 return (EPERM);
1435
1436 if(pcvt_xmode)
1437 return 0;
1438
1439 pcvt_xmode = pcvt_kbd_raw = 1;
1440
1441 for(i = 0; i < totalfonts; i++)
1442 {
1443 if(vgacs[i].loaded)
1444 {
1445 saved_fonts[i] = (unsigned char *)
1446 malloc(32 * 256, M_DEVBUF, M_WAITOK);
1447 if(saved_fonts[i] == 0)
1448 {
1449 printf(
1450 "pcvt_xmode_set: no font buffer available\n");
1451 return (EAGAIN);
1452 }
1453 else
1454 {
1455 vga_move_charset(i, saved_fonts[i], 1);
1456 }
1457 }
1458 else
1459 {
1460 saved_fonts[i] = 0;
1461 }
1462 }
1463
1464#if PCVT_SCREENSAVER
1465 if(saved_scrnsv_tmo = scrnsv_timeout)
1466 pcvt_set_scrnsv_tmo(0); /* turn it off */
1467#endif /* PCVT_SCREENSAVER */
1468
1469 async_update(UPDATE_STOP); /* turn off */
1470
1471 /* disable text output and save screen contents */
1472 /* video board memory -> kernel memory */
1473
1474 bcopy(vsp->Crtat, vsp->Memory,
1475 vsp->screen_rowsize * vsp->maxcol * CHR);
1476
1477 vsp->Crtat = vsp->Memory; /* operate in memory now */
1478
1479#ifndef _DEV_KBD_KBDREG_H_
1480
1481#if PCVT_SCANSET == 2
1482 /* put keyboard to return ancient PC scan codes */
1483 kbc_8042cmd(CONTR_WRITE);
1484#if PCVT_USEKBDSEC /* security enabled */
1485 outb(CONTROLLER_DATA,
1486 (COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1487#else /* security disabled */
1488 outb(CONTROLLER_DATA,
1489 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1490#endif /* PCVT_USEKBDSEC */
1491#endif /* PCVT_SCANSET == 2 */
1492
1493#else /* _DEV_KBD_KBDREG_H_ */
1494
1495#if PCVT_SCANSET == 2
1496 /* put keyboard to return ancient PC scan codes */
1497 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1498 KBD_TRANSLATION, KBD_TRANSLATION);
1499#endif /* PCVT_SCANSET == 2 */
1500
1501#endif /* !_DEV_KBD_KBDREG_H_ */
1502
1503#if PCVT_NETBSD > 9
1504 fp->tf_eflags |= PSL_IOPL;
1505#else
1506 fp->sf_eflags |= PSL_IOPL;
1507#endif /* PCVT_NETBSD > 9 */
1508
1509 }
1510 else
1511 {
1512 if(!pcvt_xmode) /* verify if in X */
1513 return 0;
1514
1515 pcvt_xmode = pcvt_kbd_raw = 0;
1516
1517 for(i = 0; i < totalfonts; i++)
1518 {
1519 if(saved_fonts[i])
1520 {
1521 vga_move_charset(i, saved_fonts[i], 0);
1522 free(saved_fonts[i], M_DEVBUF);
1523 saved_fonts[i] = 0;
1524 }
1525 }
1526
1527#if PCVT_NETBSD > 9
1528 fp->tf_eflags &= ~PSL_IOPL;
1529#else
1530 fp->sf_eflags &= ~PSL_IOPL;
1531#endif /* PCVT_NETBSD > 9 */
1532
1533#if PCVT_SCREENSAVER
1534 if(saved_scrnsv_tmo)
1535 pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);
1536#endif /* PCVT_SCREENSAVER */
1537
1538#ifndef _DEV_KBD_KBDREG_H_
1539
1540#if PCVT_SCANSET == 2
1541 kbc_8042cmd(CONTR_WRITE);
1542#if PCVT_USEKBDSEC /* security enabled */
1543 outb(CONTROLLER_DATA,
1544 (COMMAND_SYSFLG|COMMAND_IRQEN));
1545#else /* security disabled */
1546 outb(CONTROLLER_DATA,
1547 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN));
1548#endif /* PCVT_USEKBDSEC */
1549#endif /* PCVT_SCANSET == 2 */
1550
1551#else /* _DEV_KBD_KBDREG_H_ */
1552
1553#if PCVT_SCANSET == 2
1554 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1555 KBD_TRANSLATION, 0);
1556#endif /* PCVT_SCANSET == 2 */
1557
1558#endif /* !_DEV_KBD_KBDREG_H_ */
1559
1560 if(adaptor_type == MDA_ADAPTOR)
1561 {
1562 /*
1563 * Due to the fact that HGC registers are write-only,
1564 * the Xserver can only make guesses about the state
1565 * the HGC adaptor has been before turning on X mode.
1566 * Thus, the display must be re-enabled now, and the
1567 * cursor shape and location restored.
1568 */
1569 outb(GN_DMCNTLM, 0x28); /* enable display, text mode */
1570 outb(addr_6845, CRTC_CURSORH); /* select high register */
1571 outb(addr_6845+1,
1572 ((vsp->Crtat + vsp->cur_offset) - Crtat) >> 8);
1573 outb(addr_6845, CRTC_CURSORL); /* select low register */
1574 outb(addr_6845+1,
1575 ((vsp->Crtat + vsp->cur_offset) - Crtat));
1576
1577 outb(addr_6845, CRTC_CURSTART); /* select high register */
1578 outb(addr_6845+1, vsp->cursor_start);
1579 outb(addr_6845, CRTC_CUREND); /* select low register */
1580 outb(addr_6845+1, vsp->cursor_end);
1581 }
1582
1583 /* restore screen and re-enable text output */
1584 /* kernel memory -> video board memory */
1585
1586 bcopy(vsp->Memory, Crtat,
1587 vsp->screen_rowsize * vsp->maxcol * CHR);
1588
1589 vsp->Crtat = Crtat; /* operate on-screen now */
1590
1591 /* set crtc screen memory start address */
1592
1593 outb(addr_6845, CRTC_STARTADRH);
1594 outb(addr_6845+1, (vsp->Crtat - Crtat) >> 8);
1595 outb(addr_6845, CRTC_STARTADRL);
1596 outb(addr_6845+1, (vsp->Crtat - Crtat));
1597
1598 async_update(UPDATE_START);
1599 }
1600 return 0;
1601}
1602#endif /* XSERVER && !PCVT_USL_VT_COMPAT */
1603
1604#endif /* NVT > 0 */
1605
1606/*-------------------------- E O F -------------------------------------*/