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