2 * Copyright (c) 1999 Hellmuth Michaelis
4 * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
6 * Copyright (c) 1992, 1993 Brian Dunford-Shore and Scott Turner.
8 * Copyright (c) 1993 Charles Hannum.
10 * All rights reserved.
12 * Parts of this code regarding the NetBSD interface were written
15 * This code is derived from software contributed to Berkeley by
16 * William Jolitz and Don Ahn.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
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
31 * 4. The name authors may not be used to endorse or promote products
32 * derived from this software without specific prior written permission.
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.
46 /*---------------------------------------------------------------------------*
48 * pcvt_drv.c VT220 Driver Main Module / OS - Interface
49 * ---------------------------------------------------------
51 * Last Edit-Date: [Mon Dec 27 14:03:36 1999]
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.8 2003/08/27 06:48:15 rob Exp $
56 *---------------------------------------------------------------------------*/
61 #define EXTERN /* allocate mem */
63 #include "pcvt_hdr.h" /* global include */
65 #if PCVT_FREEBSD >= 200
67 #include <machine/stdarg.h>
69 #include "machine/stdarg.h"
72 extern int getchar (void);
75 extern u_short *Crtat;
76 #endif /* PCVT_NETBSD */
78 static void vgapelinit(void); /* read initial VGA DAC palette */
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 */
84 #ifdef _DEV_KBD_KBDREG_H_
85 static void detect_kbd(void *arg);
86 static kbd_callback_func_t pcevent;
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;
96 CONS_DRIVER(pc, pccnprobe, pccninit, pccnterm, pccngetc, pccncheckc, pccnputc,
99 static d_open_t pcopen;
100 static d_close_t pcclose;
101 static d_ioctl_t pcioctl;
102 static d_mmap_t pcmmap;
104 #define CDEV_MAJOR 12
105 static struct cdevsw pc_cdevsw = {
107 /* maj */ CDEV_MAJOR,
108 /* flags */ D_TTY | D_KQFILTER,
115 /* write */ ttywrite,
119 /* strategy */ nostrategy,
122 /* kqfilter */ ttykqfilter
125 #if PCVT_NETBSD > 100 /* NetBSD-current Feb 20 1995 */
127 pcprobe(struct device *parent, void *match, void *aux)
131 pcprobe(struct device *parent, struct device *self, void *aux)
134 pcprobe(struct isa_device *dev)
135 #endif /* PCVT_NETBSD > 9 */
136 #endif /* PCVT_NETBSD > 100 */
138 #ifdef _DEV_KBD_KBDREG_H_
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))
148 reset_keyboard = 1; /* it's now safe to do kbd reset */
149 #endif /* _DEV_KBD_KBDREG_H_ */
154 ((struct isa_attach_args *)aux)->ia_iosize = 16;
157 #ifdef _DEV_KBD_KBDREG_H_
159 #elif PCVT_NETBSD || PCVT_FREEBSD
163 #endif /* PCVT_NETBSD || PCVT_FREEBSD */
164 #endif /* PCVT_NETBSD > 9 */
170 pcattach(struct device *parent, struct device *self, void *aux)
172 struct isa_attach_args *ia = aux;
173 static struct intrhand vthand;
176 pcattach(struct isa_device *dev)
178 #endif /* PCVT_NETBSD > 9 */
182 vt_coldmalloc(); /* allocate memory for screens */
184 #ifdef _DEV_KBD_KBDREG_H_
186 timeout(detect_kbd, (void *)dev->id_unit, hz*2);
187 #endif /* _DEV_KBD_KBDREG_H_ */
189 #if PCVT_NETBSD || PCVT_FREEBSD
194 printf("vt%d: ", dev->id_unit);
195 #endif /* PCVT_NETBSD > 9 */
212 printf("%s, ", (char *)vga_string(vga_type));
214 printf("80/132 col");
230 printf(", %d scr, ", totalscreens);
232 switch(keyboard_type)
247 printf("kbd, [R%s]\n", PCVT_REL);
249 #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
251 for(i = 0; i < totalscreens; i++)
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 */
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 */
275 #else /* !PCVT_NETBSD */
277 #endif /* PCVT_NETBSD */
279 #endif /* #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
281 #else /* !PCVT_NETBSD && !PCVT_FREEBSD*/
298 printf(" <%s,", (char *)vga_string(vga_type));
300 printf("80/132 col");
316 printf(",%d scr,", totalscreens);
318 switch(keyboard_type)
333 printf("kbd,[R%s]>", PCVT_REL);
335 #endif /* PCVT_NETBSD || PCVT_FREEBSD */
337 #if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
338 for(i = 0; i < totalscreens; i++)
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);
344 #endif /* !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
346 async_update(UPDATE_START); /* start asynchronous updates */
350 vthand.ih_fun = pcrint;
352 vthand.ih_level = IPL_TTY;
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 */
360 #else /* PCVT_NETBSD > 9 */
362 dev->id_ointr = pcrint;
366 #endif /* PCVT_NETBSD > 9 */
370 /* had a look at the friedl driver */
375 get_pccons(Dev_t dev)
380 if(i == totalscreens)
381 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
385 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
386 #endif /* PCVT_EMU_MOUSE */
388 if(i >= PCVT_NSCREENS)
390 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
400 get_pccons(Dev_t dev)
405 if(i == totalscreens)
407 #endif /* PCVT_EMU_MOUSE */
409 if(i >= PCVT_NSCREENS)
414 #endif /* !PCVT_NETBSD */
416 /*---------------------------------------------------------------------------*
417 * /dev/ttyc0, /dev/ttyc1, etc.
418 *---------------------------------------------------------------------------*/
420 pcopen(Dev_t dev, int flag, int mode, struct thread *td)
423 struct video_state *vsx;
429 if(i == totalscreens)
432 #endif /* PCVT_EMU_MOUSE */
436 if((tp = get_pccons(dev)) == NULL)
442 if(i == totalscreens)
444 if(mouse.opened == 0)
445 mouse.buttons = mouse.extendedseen =
446 mouse.breakseen = mouse.lastmove.tv_sec = 0;
451 #endif /* PCVT_EMU_MOUSE */
455 tp->t_oproc = pcstart;
456 tp->t_param = pcparam;
457 tp->t_stop = nottystop;
460 if ((tp->t_state & TS_ISOPEN) == 0)
463 #ifdef TS_WOPEN /* not (FreeBSD-1.1.5 or FreeBSD some time after 2.0.5) */
464 tp->t_state |= TS_WOPEN;
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 */
477 else if (tp->t_state & TS_XCLUDE && suser(td))
480 #if PCVT_NETBSD || (PCVT_FREEBSD >= 200)
481 retval = ((*linesw[tp->t_line].l_open)(dev, tp));
483 retval = ((*linesw[tp->t_line].l_open)(dev, tp, flag));
484 #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */
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
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;
510 pcclose(Dev_t dev, int flag, int mode, struct thread *td)
513 struct video_state *vsx;
517 if(i == totalscreens)
520 #endif /* PCVT_EMU_MOUSE */
524 if((tp = get_pccons(dev)) == NULL)
527 (*linesw[tp->t_line].l_close)(tp, flag);
531 if(i == totalscreens)
534 #endif /* PCVT_EMU_MOUSE */
538 #if PCVT_USL_VT_COMPAT
541 if(i == totalscreens)
544 #endif /* PCVT_EMU_MOUSE */
546 reset_usl_modes(vsx);
548 #endif /* PCVT_USL_VT_COMPAT */
554 pcioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
559 if((tp = get_pccons(dev)) == NULL)
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
569 if(minor(dev) == totalscreens)
571 if((error = mouse_ioctl(dev, cmd, data)) >= 0)
575 #endif /* PCVT_EMU_MOUSE */
578 #if PCVT_USL_VT_COMPAT
580 if((error = usl_vt_ioctl(dev, cmd, data, flag, td->td_proc)) >= 0)
584 * just for compatibility:
585 * XFree86 < 2.0 and SuperProbe still might use it
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.
595 case CONSOLE_X_MODE_ON:
599 if((error = usl_vt_ioctl(dev, KDENABIO, 0, flag, td->td_proc)) > 0)
603 if((error = usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, td->td_proc))
608 error = usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, td->td_proc);
612 case CONSOLE_X_MODE_OFF:
616 (void)usl_vt_ioctl(dev, KDDISABIO, 0, flag, td->td_proc);
619 (void)usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, td->td_proc);
622 (void)usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, td->td_proc);
630 * If `data' is non-null, the first int value denotes
631 * the pitch, the second a duration. Otherwise, behaves
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 */
649 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
653 default: /* fall through */ ;
656 #else /* PCVT_USL_VT_COMPAT */
660 case CONSOLE_X_MODE_ON:
661 return pcvt_xmode_set(1, td->td_proc);
663 case CONSOLE_X_MODE_OFF:
664 return pcvt_xmode_set(0, td->td_proc);
669 * If `data' is non-null, the first int value denotes
670 * the pitch, the second a duration. Otherwise, behaves
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 */
688 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
692 default: /* fall through */ ;
695 #endif /* PCVT_USL_VT_COMPAT */
698 if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
701 if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
708 #if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
709 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td))
713 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag)) >= 0)
715 #endif /* PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 */
718 if((error = ttioctl(tp, cmd, data, flag, td)) >= 0)
721 if((error = ttioctl(tp, cmd, data, flag)) != ENOIOCTL)
723 #endif /* PCVT_NETBSD > 9 */
729 pcmmap(Dev_t dev, vm_offset_t offset, int nprot)
731 if (offset > 0x20000 - PAGE_SIZE)
733 return i386_btop((0xa0000 + offset));
736 /*---------------------------------------------------------------------------*
738 * handle a keyboard receive interrupt
740 * NOTE: the keyboard is multiplexed by means of "pcconsp"
741 * between virtual screens. pcconsp - switching is done in
742 * the vgapage() routine
744 *---------------------------------------------------------------------------*/
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;
755 pcvt_timeout(void *arg)
759 #if PCVT_SLOW_INTERRUPT
763 pcvt_timeout_scheduled = 0;
767 #endif /* PCVT_SCREENSAVER */
769 while (pcvt_kbd_count)
771 if (((cp = sgetc(1)) != 0) &&
772 (vs[current_video_screen].openf))
778 /* pass a NULL character */
779 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
782 #endif /* PCVT_NULLCHARS */
785 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
788 PCVT_DISABLE_INTR ();
791 pcvt_timeout_scheduled = 0;
800 #ifdef _DEV_KBD_KBDREG_H_
802 detect_kbd(void *arg)
809 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
811 kbd = kbd_get_keyboard(i);
814 reset_keyboard = 1; /* ok to reset the keyboard */
819 timeout(detect_kbd, (void *)unit, hz*2);
823 pcevent(keyboard_t *thiskbd, int event, void *arg)
828 return EINVAL; /* shouldn't happen */
834 case KBDIO_UNLOADING:
837 kbd_release(thiskbd, (void *)&kbd);
838 timeout(detect_kbd, (void *)unit, hz*4);
844 #endif /* _DEV_KBD_KBDREG_H_ */
854 # if PCVT_SLOW_INTERRUPT
858 # ifdef _DEV_KBD_KBDREG_H_
862 #else /* !PCVT_KBD_FIFO */
864 #endif /* PCVT_KBD_FIFO */
868 #endif /* PCVT_SCREENSAVER */
877 # ifndef _DEV_KBD_KBDREG_H_
878 while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) /* check 8042 buffer */
880 ret = 1; /* got something */
882 PCVT_KBD_DELAY(); /* 7 us delay */
884 dt = inb(CONTROLLER_DATA); /* get it 8042 data */
886 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
888 ret = 1; /* got something */
890 # endif /* _DEV_KBD_KBDREG_H_ */
892 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
894 log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
898 pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
900 PCVT_DISABLE_INTR (); /* XXX necessary ? */
901 pcvt_kbd_count++; /* update fifo count */
904 if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
905 pcvt_kbd_wptr = 0; /* wraparound pointer */
909 if (ret == 1) /* got data from keyboard ? */
911 if (!pcvt_timeout_scheduled) /* if not already active .. */
913 PCVT_DISABLE_INTR ();
914 pcvt_timeout_scheduled = 1; /* flag active */
915 timeout(pcvt_timeout, NULL, hz / 100); /* fire off */
920 #else /* !PCVT_KBD_FIFO */
922 if((cp = sgetc(1)) == 0)
928 if(!(vs[current_video_screen].openf)) /* XXX was vs[minor(dev)] */
934 /* pass a NULL character */
935 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
938 #endif /* PCVT_NULLCHARS */
941 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
943 #endif /* PCVT_KBD_FIFO */
947 #if PCVT_NETBSD || PCVT_FREEBSD >= 200
950 pcstart(struct tty *tp)
954 u_char buf[PCVT_PCBURST];
958 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
961 tp->t_state |= TS_BUSY;
965 async_update(UPDATE_KERN);
970 * Call q_to_b() at spltty() to ensure that the queue is empty when
971 * the loop terminates.
976 while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
978 if(vs[minor(tp->t_dev)].scrolling)
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.
986 sput(&buf[0], 0, len, minor(tp->t_dev));
990 tp->t_state &= ~TS_BUSY;
992 #ifndef TS_ASLEEP /* FreeBSD some time after 2.0.5 */
995 if (rbp->c_cc <= tp->t_lowat)
997 if (tp->t_state&TS_ASLEEP)
999 tp->t_state &= ~TS_ASLEEP;
1000 wakeup((caddr_t)rbp);
1002 selwakeup(&tp->t_wsel);
1010 pcstop(struct tty *tp, int flag)
1014 #else /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1017 pcstart(struct tty *tp)
1024 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
1032 #if !(PCVT_FREEBSD > 114)
1034 #if !(PCVT_FREEBSD > 111)
1035 if (RB_LEN(&tp->t_out) <= tp->t_lowat)
1037 if (RB_LEN(tp->t_out) <= tp->t_lowat)
1040 if (tp->t_state&TS_ASLEEP)
1042 tp->t_state &= ~TS_ASLEEP;
1043 #if !(PCVT_FREEBSD > 111)
1044 wakeup((caddr_t)&tp->t_out);
1046 wakeup((caddr_t)tp->t_out);
1052 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
1054 tp->t_state &= ~TS_WCOLL;
1058 #else /* PCVT_FREEBSD > 114 */
1059 if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT)
1063 #endif /* !PCVT_FREEBSD > 114 */
1065 #if !(PCVT_FREEBSD > 111)
1066 if (RB_LEN(&tp->t_out) == 0)
1068 if (RB_LEN(tp->t_out) == 0)
1074 #if !(PCVT_FREEBSD > 111)
1075 c = getc(&tp->t_out);
1077 c = getc(tp->t_out);
1080 tp->t_state |= TS_BUSY; /* patch from Frank Maclachlan */
1082 sput(&c, 0, 1, minor(tp->t_dev));
1084 tp->t_state &= ~TS_BUSY; /* patch from Frank Maclachlan */
1090 #endif /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1092 /*---------------------------------------------------------------------------*
1094 *---------------------------------------------------------------------------*/
1096 #if !PCVT_NETBSD /* has moved to cons.c in netbsd-current */
1098 consinit() /* init for kernel messages during boot */
1101 #endif /* PCVT_NETBSD */
1103 #if PCVT_FREEBSD > 205
1108 pccnprobe(struct consdev *cp)
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;
1119 #ifdef _DEV_KBD_KBDREG_H_
1120 kbd_configure(KB_CONF_PROBE_ONLY);
1121 if (kbd_find_keyboard("*", unit) < 0)
1123 cp->cn_pri = CN_DEAD;
1126 #endif /* _DEV_KBD_KBDREG_H_ */
1128 /* initialize required fields */
1130 cp->cn_dev = makedev(CDEV_MAJOR, 0);
1131 cp->cn_pri = CN_INTERNAL;
1135 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
1136 cp->cn_tp = &pccons[0];
1138 cp->cn_tp = pccons[0];
1139 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
1141 #endif /* !PCVT_NETBSD */
1143 #if PCVT_FREEBSD <= 205
1148 #if PCVT_FREEBSD > 205
1153 pccninit(struct consdev *cp)
1158 pcvt_is_console = 1;
1160 #ifdef _DEV_KBD_KBDREG_H_
1162 * Don't reset the keyboard via `kbdio' just yet.
1163 * The system clock has not been calibrated...
1169 kbd_release(kbd, (void *)&kbd);
1172 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
1174 kbd = kbd_get_keyboard(i);
1176 #if PCVT_SCANSET == 2
1178 * Turn off scancode translation early so that UserConfig
1179 * and DDB can read the keyboard.
1183 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
1184 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1185 KBD_TRANSLATION, 0);
1187 #endif /* PCVT_SCANSET == 2 */
1189 #endif /* _DEV_KBD_KBDREG_H_ */
1191 #if PCVT_FREEBSD <= 205
1197 pccnterm(struct consdev *cp)
1199 #ifdef _DEV_KBD_KBDREG_H_
1202 kbd_release(kbd, (void *)&kbd);
1205 #endif /* _DEV_KBD_KBDREG_H_ */
1208 #if PCVT_FREEBSD > 205
1213 pccnputc(Dev_t dev, U_char c)
1218 if(current_video_screen != 0)
1221 #if !PCVT_USL_VT_COMPAT
1224 switch_screen(0, 0);
1225 #endif /* !PCVT_USL_VT_COMPAT */
1229 #endif /* PCVT_SW0CNOUTP */
1232 sput("\r", 1, 1, 0);
1234 sput((char *) &c, 1, 1, 0);
1236 async_update(UPDATE_KERN);
1238 #if PCVT_FREEBSD <= 205
1247 static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
1252 #if !PCVT_USL_VT_COMPAT
1255 #else /* !PCVT_USL_VT_COMPAT */
1258 #endif /* !PCVT_USL_VT_COMPAT */
1260 #endif /* XSERVER */
1264 * We still have a pending key sequence, e.g.
1265 * from an arrow key. Deliver this one first.
1269 #ifdef _DEV_KBD_KBDREG_H_
1274 s = spltty(); /* block pcrint while we poll */
1276 #ifdef _DEV_KBD_KBDREG_H_
1277 (*kbdsw[kbd->kb_index]->enable)(kbd);
1280 #ifdef _DEV_KBD_KBDREG_H_
1281 (*kbdsw[kbd->kb_index]->disable)(kbd);
1287 /* Preserve the multi-char sequence for the next call. */
1288 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
1293 #if ! (PCVT_FREEBSD >= 201)
1294 /* this belongs to cons.c */
1297 #endif /* ! (PCVT_FREEBSD >= 201) */
1302 #if PCVT_FREEBSD >= 200
1304 pccncheckc(Dev_t dev)
1309 #ifdef _DEV_KBD_KBDREG_H_
1316 #ifdef _DEV_KBD_KBDREG_H_
1317 (*kbdsw[kbd->kb_index]->enable)(kbd);
1320 #ifdef _DEV_KBD_KBDREG_H_
1321 (*kbdsw[kbd->kb_index]->disable)(kbd);
1325 return (cp == NULL ? -1 : *cp);
1327 #endif /* PCVT_FREEBSD >= 200 */
1329 #if PCVT_NETBSD >= 100
1331 pccnpollc(Dev_t dev, int on)
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.
1347 #endif /* PCVT_NETBSD >= 100 */
1349 /*---------------------------------------------------------------------------*
1350 * Set line parameters
1351 *---------------------------------------------------------------------------*/
1353 pcparam(struct tty *tp, struct termios *t)
1355 int cflag = t->c_cflag;
1357 /* and copy to tty */
1359 tp->t_ispeed = t->c_ispeed;
1360 tp->t_ospeed = t->c_ospeed;
1361 tp->t_cflag = cflag;
1366 /*----------------------------------------------------------------------*
1367 * read initial VGA palette (as stored by VGA ROM BIOS) into
1369 *----------------------------------------------------------------------*/
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 */);
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));
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 *----------------------------------------------------------------------*/
1395 pcvt_xmode_set(int on, struct thread *td)
1397 static unsigned char *saved_fonts[NVGAFONTS];
1399 #if PCVT_SCREENSAVER
1400 static unsigned saved_scrnsv_tmo = 0;
1401 #endif /* PCVT_SCREENSAVER */
1403 #if (PCVT_NETBSD > 9) || (PCVT_FREEBSD > 102)
1404 struct trapframe *fp;
1406 struct syscframe *fp;
1407 #endif /* PCVT_NETBSD > 9 */
1411 /* X will only run on VGA and Hercules adaptors */
1413 if(adaptor_type != VGA_ADAPTOR && adaptor_type != MDA_ADAPTOR)
1417 fp = (struct trapframe *)p->p_regs;
1419 fp = (struct syscframe *)p->p_regs;
1420 #endif /* PCVT_NETBSD > 9 */
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.
1433 if (securelevel > 0)
1439 pcvt_xmode = pcvt_kbd_raw = 1;
1441 for(i = 0; i < totalfonts; i++)
1445 saved_fonts[i] = (unsigned char *)
1446 malloc(32 * 256, M_DEVBUF, M_WAITOK);
1447 if(saved_fonts[i] == 0)
1450 "pcvt_xmode_set: no font buffer available\n");
1455 vga_move_charset(i, saved_fonts[i], 1);
1464 #if PCVT_SCREENSAVER
1465 if(saved_scrnsv_tmo = scrnsv_timeout)
1466 pcvt_set_scrnsv_tmo(0); /* turn it off */
1467 #endif /* PCVT_SCREENSAVER */
1469 async_update(UPDATE_STOP); /* turn off */
1471 /* disable text output and save screen contents */
1472 /* video board memory -> kernel memory */
1474 bcopy(vsp->Crtat, vsp->Memory,
1475 vsp->screen_rowsize * vsp->maxcol * CHR);
1477 vsp->Crtat = vsp->Memory; /* operate in memory now */
1479 #ifndef _DEV_KBD_KBDREG_H_
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 */
1493 #else /* _DEV_KBD_KBDREG_H_ */
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 */
1501 #endif /* !_DEV_KBD_KBDREG_H_ */
1504 fp->tf_eflags |= PSL_IOPL;
1506 fp->sf_eflags |= PSL_IOPL;
1507 #endif /* PCVT_NETBSD > 9 */
1512 if(!pcvt_xmode) /* verify if in X */
1515 pcvt_xmode = pcvt_kbd_raw = 0;
1517 for(i = 0; i < totalfonts; i++)
1521 vga_move_charset(i, saved_fonts[i], 0);
1522 free(saved_fonts[i], M_DEVBUF);
1528 fp->tf_eflags &= ~PSL_IOPL;
1530 fp->sf_eflags &= ~PSL_IOPL;
1531 #endif /* PCVT_NETBSD > 9 */
1533 #if PCVT_SCREENSAVER
1534 if(saved_scrnsv_tmo)
1535 pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);
1536 #endif /* PCVT_SCREENSAVER */
1538 #ifndef _DEV_KBD_KBDREG_H_
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 */
1551 #else /* _DEV_KBD_KBDREG_H_ */
1553 #if PCVT_SCANSET == 2
1554 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1555 KBD_TRANSLATION, 0);
1556 #endif /* PCVT_SCANSET == 2 */
1558 #endif /* !_DEV_KBD_KBDREG_H_ */
1560 if(adaptor_type == MDA_ADAPTOR)
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.
1569 outb(GN_DMCNTLM, 0x28); /* enable display, text mode */
1570 outb(addr_6845, CRTC_CURSORH); /* select high register */
1572 ((vsp->Crtat + vsp->cur_offset) - Crtat) >> 8);
1573 outb(addr_6845, CRTC_CURSORL); /* select low register */
1575 ((vsp->Crtat + vsp->cur_offset) - Crtat));
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);
1583 /* restore screen and re-enable text output */
1584 /* kernel memory -> video board memory */
1586 bcopy(vsp->Memory, Crtat,
1587 vsp->screen_rowsize * vsp->maxcol * CHR);
1589 vsp->Crtat = Crtat; /* operate on-screen now */
1591 /* set crtc screen memory start address */
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));
1598 async_update(UPDATE_START);
1602 #endif /* XSERVER && !PCVT_USL_VT_COMPAT */
1604 #endif /* NVT > 0 */
1606 /*-------------------------- E O F -------------------------------------*/