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