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