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.10 2004/05/19 22:52:54 dillon 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 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 cdevsw_add(&pc_cdevsw, 0, 0);
339 for(i = 0; i < totalscreens; i++)
341 ttyregister(&pccons[i]);
342 vs[i].vs_tty = &pccons[i];
343 make_dev(&pc_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
345 #endif /* !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
347 async_update(UPDATE_START); /* start asynchronous updates */
351 vthand.ih_fun = pcrint;
353 vthand.ih_level = IPL_TTY;
355 #if (PCVT_NETBSD > 100) && defined(IST_EDGE)
356 intr_establish(ia->ia_irq, IST_EDGE, &vthand);
357 #else /* PCVT_NETBSD > 100 */
358 intr_establish(ia->ia_irq, &vthand);
359 #endif /* PCVT_NETBSD > 100 */
361 #else /* PCVT_NETBSD > 9 */
363 dev->id_ointr = pcrint;
367 #endif /* PCVT_NETBSD > 9 */
371 /* had a look at the friedl driver */
376 get_pccons(Dev_t dev)
381 if(i == totalscreens)
382 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
386 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
387 #endif /* PCVT_EMU_MOUSE */
389 if(i >= PCVT_NSCREENS)
391 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
401 get_pccons(Dev_t dev)
406 if(i == totalscreens)
408 #endif /* PCVT_EMU_MOUSE */
410 if(i >= PCVT_NSCREENS)
415 #endif /* !PCVT_NETBSD */
417 /*---------------------------------------------------------------------------*
418 * /dev/ttyc0, /dev/ttyc1, etc.
419 *---------------------------------------------------------------------------*/
421 pcopen(Dev_t dev, int flag, int mode, struct thread *td)
424 struct video_state *vsx;
430 if(i == totalscreens)
433 #endif /* PCVT_EMU_MOUSE */
437 if((tp = get_pccons(dev)) == NULL)
443 if(i == totalscreens)
445 if(mouse.opened == 0)
446 mouse.buttons = mouse.extendedseen =
447 mouse.breakseen = mouse.lastmove.tv_sec = 0;
452 #endif /* PCVT_EMU_MOUSE */
456 tp->t_oproc = pcstart;
457 tp->t_param = pcparam;
458 tp->t_stop = nottystop;
461 if ((tp->t_state & TS_ISOPEN) == 0)
464 #ifdef TS_WOPEN /* not (FreeBSD-1.1.5 or FreeBSD some time after 2.0.5) */
465 tp->t_state |= TS_WOPEN;
469 tp->t_iflag = TTYDEF_IFLAG;
470 tp->t_oflag = TTYDEF_OFLAG;
471 tp->t_cflag = TTYDEF_CFLAG;
472 tp->t_lflag = TTYDEF_LFLAG;
473 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
474 pcparam(tp, &tp->t_termios);
475 (*linesw[tp->t_line].l_modem)(tp, 1); /* fake connection */
476 winsz = 1; /* set winsize later */
478 else if (tp->t_state & TS_XCLUDE && suser(td))
481 #if PCVT_NETBSD || (PCVT_FREEBSD >= 200)
482 retval = ((*linesw[tp->t_line].l_open)(dev, tp));
484 retval = ((*linesw[tp->t_line].l_open)(dev, tp, flag));
485 #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */
491 * The line discipline has clobbered t_winsize if TS_ISOPEN
492 * was clear. (NetBSD PR #400 from Bill Sommerfeld)
493 * We have to do this after calling the open routine, because
494 * it does some other things in other/older *BSD releases -hm
499 tp->t_winsize.ws_col = vsx->maxcol;
500 tp->t_winsize.ws_row = vsx->screen_rows;
501 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
502 tp->t_winsize.ws_ypixel = 400;
511 pcclose(Dev_t dev, int flag, int mode, struct thread *td)
514 struct video_state *vsx;
518 if(i == totalscreens)
521 #endif /* PCVT_EMU_MOUSE */
525 if((tp = get_pccons(dev)) == NULL)
528 (*linesw[tp->t_line].l_close)(tp, flag);
532 if(i == totalscreens)
535 #endif /* PCVT_EMU_MOUSE */
539 #if PCVT_USL_VT_COMPAT
542 if(i == totalscreens)
545 #endif /* PCVT_EMU_MOUSE */
547 reset_usl_modes(vsx);
549 #endif /* PCVT_USL_VT_COMPAT */
555 pcioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
560 if((tp = get_pccons(dev)) == NULL)
563 /* note that some ioctl's are global, e.g. KBSTPMAT: There is
564 * only one keyboard and different repeat rates for instance between
565 * sessions are a suspicious wish. If you really need this make the
566 * appropriate variables arrays
570 if(minor(dev) == totalscreens)
572 if((error = mouse_ioctl(dev, cmd, data)) >= 0)
576 #endif /* PCVT_EMU_MOUSE */
579 #if PCVT_USL_VT_COMPAT
581 if((error = usl_vt_ioctl(dev, cmd, data, flag, td->td_proc)) >= 0)
585 * just for compatibility:
586 * XFree86 < 2.0 and SuperProbe still might use it
588 * NB: THIS IS A HACK! Do not use it unless you explicitly need.
589 * Especially, since the vty is not put into process-controlled
590 * mode (this would require the application to co-operate), any
591 * attempts to switch vtys while this kind of X mode is active
592 * may cause serious trouble.
596 case CONSOLE_X_MODE_ON:
600 if((error = usl_vt_ioctl(dev, KDENABIO, 0, flag, td->td_proc)) > 0)
604 if((error = usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, td->td_proc))
609 error = usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, td->td_proc);
613 case CONSOLE_X_MODE_OFF:
617 (void)usl_vt_ioctl(dev, KDDISABIO, 0, flag, td->td_proc);
620 (void)usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, td->td_proc);
623 (void)usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, td->td_proc);
631 * If `data' is non-null, the first int value denotes
632 * the pitch, the second a duration. Otherwise, behaves
640 sysbeep(((int *)data)[0],
641 ((int *)data)[1] * hz / 1000);
642 #else /* PCVT_NETBSD */
643 sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
644 ((int *)data)[1] * hz / 3000);
645 #endif /* PCVT_NETBSD */
650 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
654 default: /* fall through */ ;
657 #else /* PCVT_USL_VT_COMPAT */
661 case CONSOLE_X_MODE_ON:
662 return pcvt_xmode_set(1, td->td_proc);
664 case CONSOLE_X_MODE_OFF:
665 return pcvt_xmode_set(0, td->td_proc);
670 * If `data' is non-null, the first int value denotes
671 * the pitch, the second a duration. Otherwise, behaves
679 sysbeep(((int *)data)[0],
680 ((int *)data)[1] * hz / 1000);
681 #else /* PCVT_NETBSD */
682 sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
683 ((int *)data)[1] * hz / 3000);
684 #endif /* PCVT_NETBSD */
689 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
693 default: /* fall through */ ;
696 #endif /* PCVT_USL_VT_COMPAT */
699 if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
702 if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
709 #if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
710 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td))
714 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag)) >= 0)
716 #endif /* PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 */
719 if((error = ttioctl(tp, cmd, data, flag, td)) >= 0)
722 if((error = ttioctl(tp, cmd, data, flag)) != ENOIOCTL)
724 #endif /* PCVT_NETBSD > 9 */
730 pcmmap(Dev_t dev, vm_offset_t offset, int nprot)
732 if (offset > 0x20000 - PAGE_SIZE)
734 return i386_btop((0xa0000 + offset));
737 /*---------------------------------------------------------------------------*
739 * handle a keyboard receive interrupt
741 * NOTE: the keyboard is multiplexed by means of "pcconsp"
742 * between virtual screens. pcconsp - switching is done in
743 * the vgapage() routine
745 *---------------------------------------------------------------------------*/
749 u_char pcvt_kbd_fifo[PCVT_KBD_FIFO_SZ];
750 static int pcvt_kbd_wptr = 0;
751 int pcvt_kbd_rptr = 0;
752 short pcvt_kbd_count= 0;
753 static u_char pcvt_timeout_scheduled = 0;
756 pcvt_timeout(void *arg)
760 #if PCVT_SLOW_INTERRUPT
764 pcvt_timeout_scheduled = 0;
768 #endif /* PCVT_SCREENSAVER */
770 while (pcvt_kbd_count)
772 if (((cp = sgetc(1)) != 0) &&
773 (vs[current_video_screen].openf))
779 /* pass a NULL character */
780 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
783 #endif /* PCVT_NULLCHARS */
786 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
789 PCVT_DISABLE_INTR ();
792 pcvt_timeout_scheduled = 0;
801 #ifdef _DEV_KBD_KBDREG_H_
803 detect_kbd(void *arg)
810 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
812 kbd = kbd_get_keyboard(i);
815 reset_keyboard = 1; /* ok to reset the keyboard */
820 timeout(detect_kbd, (void *)unit, hz*2);
824 pcevent(keyboard_t *thiskbd, int event, void *arg)
829 return EINVAL; /* shouldn't happen */
835 case KBDIO_UNLOADING:
838 kbd_release(thiskbd, (void *)&kbd);
839 timeout(detect_kbd, (void *)unit, hz*4);
845 #endif /* _DEV_KBD_KBDREG_H_ */
855 # if PCVT_SLOW_INTERRUPT
859 # ifdef _DEV_KBD_KBDREG_H_
863 #else /* !PCVT_KBD_FIFO */
865 #endif /* PCVT_KBD_FIFO */
869 #endif /* PCVT_SCREENSAVER */
878 # ifndef _DEV_KBD_KBDREG_H_
879 while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) /* check 8042 buffer */
881 ret = 1; /* got something */
883 PCVT_KBD_DELAY(); /* 7 us delay */
885 dt = inb(CONTROLLER_DATA); /* get it 8042 data */
887 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
889 ret = 1; /* got something */
891 # endif /* _DEV_KBD_KBDREG_H_ */
893 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
895 log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
899 pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
901 PCVT_DISABLE_INTR (); /* XXX necessary ? */
902 pcvt_kbd_count++; /* update fifo count */
905 if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
906 pcvt_kbd_wptr = 0; /* wraparound pointer */
910 if (ret == 1) /* got data from keyboard ? */
912 if (!pcvt_timeout_scheduled) /* if not already active .. */
914 PCVT_DISABLE_INTR ();
915 pcvt_timeout_scheduled = 1; /* flag active */
916 timeout(pcvt_timeout, NULL, hz / 100); /* fire off */
921 #else /* !PCVT_KBD_FIFO */
923 if((cp = sgetc(1)) == 0)
929 if(!(vs[current_video_screen].openf)) /* XXX was vs[minor(dev)] */
935 /* pass a NULL character */
936 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
939 #endif /* PCVT_NULLCHARS */
942 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
944 #endif /* PCVT_KBD_FIFO */
948 #if PCVT_NETBSD || PCVT_FREEBSD >= 200
951 pcstart(struct tty *tp)
955 u_char buf[PCVT_PCBURST];
959 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
962 tp->t_state |= TS_BUSY;
966 async_update(UPDATE_KERN);
971 * Call q_to_b() at spltty() to ensure that the queue is empty when
972 * the loop terminates.
977 while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
979 if(vs[minor(tp->t_dev)].scrolling)
983 * We need to do this outside spl since it could be fairly
984 * expensive and we don't want our serial ports to overflow.
987 sput(&buf[0], 0, len, minor(tp->t_dev));
991 tp->t_state &= ~TS_BUSY;
993 #ifndef TS_ASLEEP /* FreeBSD some time after 2.0.5 */
996 if (rbp->c_cc <= tp->t_lowat)
998 if (tp->t_state&TS_ASLEEP)
1000 tp->t_state &= ~TS_ASLEEP;
1001 wakeup((caddr_t)rbp);
1003 selwakeup(&tp->t_wsel);
1011 pcstop(struct tty *tp, int flag)
1015 #else /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1018 pcstart(struct tty *tp)
1025 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
1033 #if !(PCVT_FREEBSD > 114)
1035 #if !(PCVT_FREEBSD > 111)
1036 if (RB_LEN(&tp->t_out) <= tp->t_lowat)
1038 if (RB_LEN(tp->t_out) <= tp->t_lowat)
1041 if (tp->t_state&TS_ASLEEP)
1043 tp->t_state &= ~TS_ASLEEP;
1044 #if !(PCVT_FREEBSD > 111)
1045 wakeup((caddr_t)&tp->t_out);
1047 wakeup((caddr_t)tp->t_out);
1053 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
1055 tp->t_state &= ~TS_WCOLL;
1059 #else /* PCVT_FREEBSD > 114 */
1060 if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT)
1064 #endif /* !PCVT_FREEBSD > 114 */
1066 #if !(PCVT_FREEBSD > 111)
1067 if (RB_LEN(&tp->t_out) == 0)
1069 if (RB_LEN(tp->t_out) == 0)
1075 #if !(PCVT_FREEBSD > 111)
1076 c = getc(&tp->t_out);
1078 c = getc(tp->t_out);
1081 tp->t_state |= TS_BUSY; /* patch from Frank Maclachlan */
1083 sput(&c, 0, 1, minor(tp->t_dev));
1085 tp->t_state &= ~TS_BUSY; /* patch from Frank Maclachlan */
1091 #endif /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1093 /*---------------------------------------------------------------------------*
1095 *---------------------------------------------------------------------------*/
1097 #if !PCVT_NETBSD /* has moved to cons.c in netbsd-current */
1099 consinit() /* init for kernel messages during boot */
1102 #endif /* PCVT_NETBSD */
1104 #if PCVT_FREEBSD > 205
1109 pccnprobe(struct consdev *cp)
1114 /* See if this driver is disabled in probe hint. */
1115 if (resource_int_value("vt", unit, "disabled", &i) == 0 && i) {
1116 cp->cn_pri = CN_DEAD;
1120 #ifdef _DEV_KBD_KBDREG_H_
1121 kbd_configure(KB_CONF_PROBE_ONLY);
1122 if (kbd_find_keyboard("*", unit) < 0)
1124 cp->cn_pri = CN_DEAD;
1127 #endif /* _DEV_KBD_KBDREG_H_ */
1129 /* initialize required fields */
1131 cp->cn_dev = make_adhoc_dev(&pc_cdevsw, 0);
1132 cp->cn_pri = CN_INTERNAL;
1136 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
1137 cp->cn_tp = &pccons[0];
1139 cp->cn_tp = pccons[0];
1140 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
1142 #endif /* !PCVT_NETBSD */
1144 #if PCVT_FREEBSD <= 205
1149 #if PCVT_FREEBSD > 205
1154 pccninit(struct consdev *cp)
1159 pcvt_is_console = 1;
1161 #ifdef _DEV_KBD_KBDREG_H_
1163 * Don't reset the keyboard via `kbdio' just yet.
1164 * The system clock has not been calibrated...
1170 kbd_release(kbd, (void *)&kbd);
1173 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
1175 kbd = kbd_get_keyboard(i);
1177 #if PCVT_SCANSET == 2
1179 * Turn off scancode translation early so that UserConfig
1180 * and DDB can read the keyboard.
1184 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
1185 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1186 KBD_TRANSLATION, 0);
1188 #endif /* PCVT_SCANSET == 2 */
1190 #endif /* _DEV_KBD_KBDREG_H_ */
1192 #if PCVT_FREEBSD <= 205
1198 pccnterm(struct consdev *cp)
1200 #ifdef _DEV_KBD_KBDREG_H_
1203 kbd_release(kbd, (void *)&kbd);
1206 #endif /* _DEV_KBD_KBDREG_H_ */
1209 #if PCVT_FREEBSD > 205
1214 pccnputc(Dev_t dev, U_char c)
1219 if(current_video_screen != 0)
1222 #if !PCVT_USL_VT_COMPAT
1225 switch_screen(0, 0);
1226 #endif /* !PCVT_USL_VT_COMPAT */
1230 #endif /* PCVT_SW0CNOUTP */
1233 sput("\r", 1, 1, 0);
1235 sput((char *) &c, 1, 1, 0);
1237 async_update(UPDATE_KERN);
1239 #if PCVT_FREEBSD <= 205
1248 static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
1253 #if !PCVT_USL_VT_COMPAT
1256 #else /* !PCVT_USL_VT_COMPAT */
1259 #endif /* !PCVT_USL_VT_COMPAT */
1261 #endif /* XSERVER */
1265 * We still have a pending key sequence, e.g.
1266 * from an arrow key. Deliver this one first.
1270 #ifdef _DEV_KBD_KBDREG_H_
1275 s = spltty(); /* block pcrint while we poll */
1277 #ifdef _DEV_KBD_KBDREG_H_
1278 (*kbdsw[kbd->kb_index]->enable)(kbd);
1281 #ifdef _DEV_KBD_KBDREG_H_
1282 (*kbdsw[kbd->kb_index]->disable)(kbd);
1288 /* Preserve the multi-char sequence for the next call. */
1289 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
1294 #if ! (PCVT_FREEBSD >= 201)
1295 /* this belongs to cons.c */
1298 #endif /* ! (PCVT_FREEBSD >= 201) */
1303 #if PCVT_FREEBSD >= 200
1305 pccncheckc(Dev_t dev)
1310 #ifdef _DEV_KBD_KBDREG_H_
1317 #ifdef _DEV_KBD_KBDREG_H_
1318 (*kbdsw[kbd->kb_index]->enable)(kbd);
1321 #ifdef _DEV_KBD_KBDREG_H_
1322 (*kbdsw[kbd->kb_index]->disable)(kbd);
1326 return (cp == NULL ? -1 : *cp);
1328 #endif /* PCVT_FREEBSD >= 200 */
1330 #if PCVT_NETBSD >= 100
1332 pccnpollc(Dev_t dev, int on)
1339 * If disabling polling, make sure there are no bytes left in
1340 * the FIFO, holding up the interrupt line. Otherwise we
1341 * won't get any further interrupts.
1348 #endif /* PCVT_NETBSD >= 100 */
1350 /*---------------------------------------------------------------------------*
1351 * Set line parameters
1352 *---------------------------------------------------------------------------*/
1354 pcparam(struct tty *tp, struct termios *t)
1356 int cflag = t->c_cflag;
1358 /* and copy to tty */
1360 tp->t_ispeed = t->c_ispeed;
1361 tp->t_ospeed = t->c_ospeed;
1362 tp->t_cflag = cflag;
1367 /*----------------------------------------------------------------------*
1368 * read initial VGA palette (as stored by VGA ROM BIOS) into
1370 *----------------------------------------------------------------------*/
1377 /* first, read all and store to first screen's save buffer */
1378 for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
1379 vgapaletteio(idx, val, 0 /* read it */);
1381 /* now, duplicate for remaining screens */
1382 for(idx = 1; idx < PCVT_NSCREENS; idx++)
1383 bcopy(vs[0].palette, vs[idx].palette,
1384 NVGAPEL * sizeof(struct rgb));
1387 #if defined XSERVER && !PCVT_USL_VT_COMPAT
1388 /*----------------------------------------------------------------------*
1389 * initialize for X mode
1390 * i.e.: grant current process (the X server) all IO privileges,
1391 * and mark in static variable so other hooks can test for it,
1392 * save all loaded fonts and screen pages to pageable buffers;
1393 * if parameter `on' is false, the same procedure is done reverse.
1394 *----------------------------------------------------------------------*/
1396 pcvt_xmode_set(int on, struct thread *td)
1398 static unsigned char *saved_fonts[NVGAFONTS];
1400 #if PCVT_SCREENSAVER
1401 static unsigned saved_scrnsv_tmo = 0;
1402 #endif /* PCVT_SCREENSAVER */
1404 #if (PCVT_NETBSD > 9) || (PCVT_FREEBSD > 102)
1405 struct trapframe *fp;
1407 struct syscframe *fp;
1408 #endif /* PCVT_NETBSD > 9 */
1412 /* X will only run on VGA and Hercules adaptors */
1414 if(adaptor_type != VGA_ADAPTOR && adaptor_type != MDA_ADAPTOR)
1418 fp = (struct trapframe *)p->p_regs;
1420 fp = (struct syscframe *)p->p_regs;
1421 #endif /* PCVT_NETBSD > 9 */
1426 * Test whether the calling process has super-user privileges
1427 * and we're in insecure mode.
1428 * This prevents us from granting the potential security hole
1429 * `IO priv' to insufficiently privileged processes.
1434 if (securelevel > 0)
1440 pcvt_xmode = pcvt_kbd_raw = 1;
1442 for(i = 0; i < totalfonts; i++)
1446 saved_fonts[i] = (unsigned char *)
1447 malloc(32 * 256, M_DEVBUF, M_WAITOK);
1448 if(saved_fonts[i] == 0)
1451 "pcvt_xmode_set: no font buffer available\n");
1456 vga_move_charset(i, saved_fonts[i], 1);
1465 #if PCVT_SCREENSAVER
1466 if(saved_scrnsv_tmo = scrnsv_timeout)
1467 pcvt_set_scrnsv_tmo(0); /* turn it off */
1468 #endif /* PCVT_SCREENSAVER */
1470 async_update(UPDATE_STOP); /* turn off */
1472 /* disable text output and save screen contents */
1473 /* video board memory -> kernel memory */
1475 bcopy(vsp->Crtat, vsp->Memory,
1476 vsp->screen_rowsize * vsp->maxcol * CHR);
1478 vsp->Crtat = vsp->Memory; /* operate in memory now */
1480 #ifndef _DEV_KBD_KBDREG_H_
1482 #if PCVT_SCANSET == 2
1483 /* put keyboard to return ancient PC scan codes */
1484 kbc_8042cmd(CONTR_WRITE);
1485 #if PCVT_USEKBDSEC /* security enabled */
1486 outb(CONTROLLER_DATA,
1487 (COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1488 #else /* security disabled */
1489 outb(CONTROLLER_DATA,
1490 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1491 #endif /* PCVT_USEKBDSEC */
1492 #endif /* PCVT_SCANSET == 2 */
1494 #else /* _DEV_KBD_KBDREG_H_ */
1496 #if PCVT_SCANSET == 2
1497 /* put keyboard to return ancient PC scan codes */
1498 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1499 KBD_TRANSLATION, KBD_TRANSLATION);
1500 #endif /* PCVT_SCANSET == 2 */
1502 #endif /* !_DEV_KBD_KBDREG_H_ */
1505 fp->tf_eflags |= PSL_IOPL;
1507 fp->sf_eflags |= PSL_IOPL;
1508 #endif /* PCVT_NETBSD > 9 */
1513 if(!pcvt_xmode) /* verify if in X */
1516 pcvt_xmode = pcvt_kbd_raw = 0;
1518 for(i = 0; i < totalfonts; i++)
1522 vga_move_charset(i, saved_fonts[i], 0);
1523 free(saved_fonts[i], M_DEVBUF);
1529 fp->tf_eflags &= ~PSL_IOPL;
1531 fp->sf_eflags &= ~PSL_IOPL;
1532 #endif /* PCVT_NETBSD > 9 */
1534 #if PCVT_SCREENSAVER
1535 if(saved_scrnsv_tmo)
1536 pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);
1537 #endif /* PCVT_SCREENSAVER */
1539 #ifndef _DEV_KBD_KBDREG_H_
1541 #if PCVT_SCANSET == 2
1542 kbc_8042cmd(CONTR_WRITE);
1543 #if PCVT_USEKBDSEC /* security enabled */
1544 outb(CONTROLLER_DATA,
1545 (COMMAND_SYSFLG|COMMAND_IRQEN));
1546 #else /* security disabled */
1547 outb(CONTROLLER_DATA,
1548 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN));
1549 #endif /* PCVT_USEKBDSEC */
1550 #endif /* PCVT_SCANSET == 2 */
1552 #else /* _DEV_KBD_KBDREG_H_ */
1554 #if PCVT_SCANSET == 2
1555 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1556 KBD_TRANSLATION, 0);
1557 #endif /* PCVT_SCANSET == 2 */
1559 #endif /* !_DEV_KBD_KBDREG_H_ */
1561 if(adaptor_type == MDA_ADAPTOR)
1564 * Due to the fact that HGC registers are write-only,
1565 * the Xserver can only make guesses about the state
1566 * the HGC adaptor has been before turning on X mode.
1567 * Thus, the display must be re-enabled now, and the
1568 * cursor shape and location restored.
1570 outb(GN_DMCNTLM, 0x28); /* enable display, text mode */
1571 outb(addr_6845, CRTC_CURSORH); /* select high register */
1573 ((vsp->Crtat + vsp->cur_offset) - Crtat) >> 8);
1574 outb(addr_6845, CRTC_CURSORL); /* select low register */
1576 ((vsp->Crtat + vsp->cur_offset) - Crtat));
1578 outb(addr_6845, CRTC_CURSTART); /* select high register */
1579 outb(addr_6845+1, vsp->cursor_start);
1580 outb(addr_6845, CRTC_CUREND); /* select low register */
1581 outb(addr_6845+1, vsp->cursor_end);
1584 /* restore screen and re-enable text output */
1585 /* kernel memory -> video board memory */
1587 bcopy(vsp->Memory, Crtat,
1588 vsp->screen_rowsize * vsp->maxcol * CHR);
1590 vsp->Crtat = Crtat; /* operate on-screen now */
1592 /* set crtc screen memory start address */
1594 outb(addr_6845, CRTC_STARTADRH);
1595 outb(addr_6845+1, (vsp->Crtat - Crtat) >> 8);
1596 outb(addr_6845, CRTC_STARTADRL);
1597 outb(addr_6845+1, (vsp->Crtat - Crtat));
1599 async_update(UPDATE_START);
1603 #endif /* XSERVER && !PCVT_USL_VT_COMPAT */
1605 #endif /* NVT > 0 */
1607 /*-------------------------- E O F -------------------------------------*/