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.2 2003/06/17 04:28:38 dillon Exp $
56 *---------------------------------------------------------------------------*/
61 #define EXTERN /* allocate mem */
63 #include <i386/isa/pcvt/pcvt_hdr.h> /* global include */
65 #if PCVT_FREEBSD >= 200
67 #include <machine/stdarg.h>
69 #include "machine/stdarg.h"
72 extern int getchar __P((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 proc *p); /* 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 = {
109 /* write */ ttywrite,
113 /* strategy */ nostrategy,
115 /* maj */ CDEV_MAJOR,
118 /* flags */ D_TTY | D_KQFILTER,
120 /* kqfilter */ ttykqfilter,
123 #if PCVT_NETBSD > 100 /* NetBSD-current Feb 20 1995 */
125 pcprobe(struct device *parent, void *match, void *aux)
129 pcprobe(struct device *parent, struct device *self, void *aux)
132 pcprobe(struct isa_device *dev)
133 #endif /* PCVT_NETBSD > 9 */
134 #endif /* PCVT_NETBSD > 100 */
136 #ifdef _DEV_KBD_KBDREG_H_
141 kbd_configure(KB_CONF_PROBE_ONLY);
142 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)dev->id_unit);
143 if ((i < 0) || ((kbd = kbd_get_keyboard(i)) == NULL))
146 reset_keyboard = 1; /* it's now safe to do kbd reset */
147 #endif /* _DEV_KBD_KBDREG_H_ */
152 ((struct isa_attach_args *)aux)->ia_iosize = 16;
155 #ifdef _DEV_KBD_KBDREG_H_
157 #elif PCVT_NETBSD || PCVT_FREEBSD
161 #endif /* PCVT_NETBSD || PCVT_FREEBSD */
162 #endif /* PCVT_NETBSD > 9 */
168 pcattach(struct device *parent, struct device *self, void *aux)
170 struct isa_attach_args *ia = aux;
171 static struct intrhand vthand;
174 pcattach(struct isa_device *dev)
176 #endif /* PCVT_NETBSD > 9 */
180 vt_coldmalloc(); /* allocate memory for screens */
182 #ifdef _DEV_KBD_KBDREG_H_
184 timeout(detect_kbd, (void *)dev->id_unit, hz*2);
185 #endif /* _DEV_KBD_KBDREG_H_ */
187 #if PCVT_NETBSD || PCVT_FREEBSD
192 printf("vt%d: ", dev->id_unit);
193 #endif /* PCVT_NETBSD > 9 */
210 printf("%s, ", (char *)vga_string(vga_type));
212 printf("80/132 col");
228 printf(", %d scr, ", totalscreens);
230 switch(keyboard_type)
245 printf("kbd, [R%s]\n", PCVT_REL);
247 #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
249 for(i = 0; i < totalscreens; i++)
253 pc_tty[i] = ttymalloc();
254 vs[i].vs_tty = pc_tty[i];
255 #else /* !PCVT_NETBSD */
256 pccons[i] = ttymalloc(pccons[i]);
257 vs[i].vs_tty = pccons[i];
258 #endif /* PCVT_NETBSD */
264 pc_tty[totalscreens] = ttymalloc(); /* the mouse emulator tty */
265 #else /* !PCVT_NETBSD */
266 /* the mouse emulator tty */
267 pc_tty[totalscreens] = ttymalloc(pccons[totalscreens]);
268 #endif /* PCVT_NETBSD */
269 #endif /* PCVT_EMU_MOUSE */
273 #else /* !PCVT_NETBSD */
275 #endif /* PCVT_NETBSD */
277 #endif /* #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
279 #else /* !PCVT_NETBSD && !PCVT_FREEBSD*/
296 printf(" <%s,", (char *)vga_string(vga_type));
298 printf("80/132 col");
314 printf(",%d scr,", totalscreens);
316 switch(keyboard_type)
331 printf("kbd,[R%s]>", PCVT_REL);
333 #endif /* PCVT_NETBSD || PCVT_FREEBSD */
335 #if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
336 for(i = 0; i < totalscreens; i++)
338 ttyregister(&pccons[i]);
339 vs[i].vs_tty = &pccons[i];
340 make_dev(&pc_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
342 #endif /* !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
344 async_update(UPDATE_START); /* start asynchronous updates */
348 vthand.ih_fun = pcrint;
350 vthand.ih_level = IPL_TTY;
352 #if (PCVT_NETBSD > 100) && defined(IST_EDGE)
353 intr_establish(ia->ia_irq, IST_EDGE, &vthand);
354 #else /* PCVT_NETBSD > 100 */
355 intr_establish(ia->ia_irq, &vthand);
356 #endif /* PCVT_NETBSD > 100 */
358 #else /* PCVT_NETBSD > 9 */
360 dev->id_ointr = pcrint;
364 #endif /* PCVT_NETBSD > 9 */
368 /* had a look at the friedl driver */
373 get_pccons(Dev_t dev)
375 register int i = minor(dev);
378 if(i == totalscreens)
379 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
383 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
384 #endif /* PCVT_EMU_MOUSE */
386 if(i >= PCVT_NSCREENS)
388 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
398 get_pccons(Dev_t dev)
400 register int i = minor(dev);
403 if(i == totalscreens)
405 #endif /* PCVT_EMU_MOUSE */
407 if(i >= PCVT_NSCREENS)
412 #endif /* !PCVT_NETBSD */
414 /*---------------------------------------------------------------------------*
415 * /dev/ttyc0, /dev/ttyc1, etc.
416 *---------------------------------------------------------------------------*/
418 pcopen(Dev_t dev, int flag, int mode, struct proc *p)
420 register struct tty *tp;
421 register struct video_state *vsx;
427 if(i == totalscreens)
430 #endif /* PCVT_EMU_MOUSE */
434 if((tp = get_pccons(dev)) == NULL)
440 if(i == totalscreens)
442 if(mouse.opened == 0)
443 mouse.buttons = mouse.extendedseen =
444 mouse.breakseen = mouse.lastmove.tv_sec = 0;
449 #endif /* PCVT_EMU_MOUSE */
453 tp->t_oproc = pcstart;
454 tp->t_param = pcparam;
455 tp->t_stop = nottystop;
458 if ((tp->t_state & TS_ISOPEN) == 0)
461 #ifdef TS_WOPEN /* not (FreeBSD-1.1.5 or FreeBSD some time after 2.0.5) */
462 tp->t_state |= TS_WOPEN;
466 tp->t_iflag = TTYDEF_IFLAG;
467 tp->t_oflag = TTYDEF_OFLAG;
468 tp->t_cflag = TTYDEF_CFLAG;
469 tp->t_lflag = TTYDEF_LFLAG;
470 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
471 pcparam(tp, &tp->t_termios);
472 (*linesw[tp->t_line].l_modem)(tp, 1); /* fake connection */
473 winsz = 1; /* set winsize later */
475 else if (tp->t_state & TS_XCLUDE && suser(p))
478 #if PCVT_NETBSD || (PCVT_FREEBSD >= 200)
479 retval = ((*linesw[tp->t_line].l_open)(dev, tp));
481 retval = ((*linesw[tp->t_line].l_open)(dev, tp, flag));
482 #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */
488 * The line discipline has clobbered t_winsize if TS_ISOPEN
489 * was clear. (NetBSD PR #400 from Bill Sommerfeld)
490 * We have to do this after calling the open routine, because
491 * it does some other things in other/older *BSD releases -hm
496 tp->t_winsize.ws_col = vsx->maxcol;
497 tp->t_winsize.ws_row = vsx->screen_rows;
498 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
499 tp->t_winsize.ws_ypixel = 400;
508 pcclose(Dev_t dev, int flag, int mode, struct proc *p)
510 register struct tty *tp;
511 register struct video_state *vsx;
515 if(i == totalscreens)
518 #endif /* PCVT_EMU_MOUSE */
522 if((tp = get_pccons(dev)) == NULL)
525 (*linesw[tp->t_line].l_close)(tp, flag);
529 if(i == totalscreens)
532 #endif /* PCVT_EMU_MOUSE */
536 #if PCVT_USL_VT_COMPAT
539 if(i == totalscreens)
542 #endif /* PCVT_EMU_MOUSE */
544 reset_usl_modes(vsx);
546 #endif /* PCVT_USL_VT_COMPAT */
552 pcioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
555 register struct tty *tp;
557 if((tp = get_pccons(dev)) == NULL)
560 /* note that some ioctl's are global, e.g. KBSTPMAT: There is
561 * only one keyboard and different repeat rates for instance between
562 * sessions are a suspicious wish. If you really need this make the
563 * appropriate variables arrays
567 if(minor(dev) == totalscreens)
569 if((error = mouse_ioctl(dev, cmd, data)) >= 0)
573 #endif /* PCVT_EMU_MOUSE */
576 #if PCVT_USL_VT_COMPAT
578 if((error = usl_vt_ioctl(dev, cmd, data, flag, p)) >= 0)
582 * just for compatibility:
583 * XFree86 < 2.0 and SuperProbe still might use it
585 * NB: THIS IS A HACK! Do not use it unless you explicitly need.
586 * Especially, since the vty is not put into process-controlled
587 * mode (this would require the application to co-operate), any
588 * attempts to switch vtys while this kind of X mode is active
589 * may cause serious trouble.
593 case CONSOLE_X_MODE_ON:
597 if((error = usl_vt_ioctl(dev, KDENABIO, 0, flag, p)) > 0)
601 if((error = usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, p))
606 error = usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, p);
610 case CONSOLE_X_MODE_OFF:
614 (void)usl_vt_ioctl(dev, KDDISABIO, 0, flag, p);
617 (void)usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, p);
620 (void)usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, p);
628 * If `data' is non-null, the first int value denotes
629 * the pitch, the second a duration. Otherwise, behaves
637 sysbeep(((int *)data)[0],
638 ((int *)data)[1] * hz / 1000);
639 #else /* PCVT_NETBSD */
640 sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
641 ((int *)data)[1] * hz / 3000);
642 #endif /* PCVT_NETBSD */
647 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
651 default: /* fall through */ ;
654 #else /* PCVT_USL_VT_COMPAT */
658 case CONSOLE_X_MODE_ON:
659 return pcvt_xmode_set(1, p);
661 case CONSOLE_X_MODE_OFF:
662 return pcvt_xmode_set(0, p);
667 * If `data' is non-null, the first int value denotes
668 * the pitch, the second a duration. Otherwise, behaves
676 sysbeep(((int *)data)[0],
677 ((int *)data)[1] * hz / 1000);
678 #else /* PCVT_NETBSD */
679 sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
680 ((int *)data)[1] * hz / 3000);
681 #endif /* PCVT_NETBSD */
686 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
690 default: /* fall through */ ;
693 #endif /* PCVT_USL_VT_COMPAT */
696 if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
699 if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
706 #if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
707 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p))
711 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag)) >= 0)
713 #endif /* PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 */
716 if((error = ttioctl(tp, cmd, data, flag, p)) >= 0)
719 if((error = ttioctl(tp, cmd, data, flag)) != ENOIOCTL)
721 #endif /* PCVT_NETBSD > 9 */
727 pcmmap(Dev_t dev, vm_offset_t offset, int nprot)
729 if (offset > 0x20000 - PAGE_SIZE)
731 return i386_btop((0xa0000 + offset));
734 /*---------------------------------------------------------------------------*
736 * handle a keyboard receive interrupt
738 * NOTE: the keyboard is multiplexed by means of "pcconsp"
739 * between virtual screens. pcconsp - switching is done in
740 * the vgapage() routine
742 *---------------------------------------------------------------------------*/
746 u_char pcvt_kbd_fifo[PCVT_KBD_FIFO_SZ];
747 static int pcvt_kbd_wptr = 0;
748 int pcvt_kbd_rptr = 0;
749 short pcvt_kbd_count= 0;
750 static u_char pcvt_timeout_scheduled = 0;
753 pcvt_timeout(void *arg)
757 #if PCVT_SLOW_INTERRUPT
761 pcvt_timeout_scheduled = 0;
765 #endif /* PCVT_SCREENSAVER */
767 while (pcvt_kbd_count)
769 if (((cp = sgetc(1)) != 0) &&
770 (vs[current_video_screen].openf))
776 /* pass a NULL character */
777 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
780 #endif /* PCVT_NULLCHARS */
783 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
786 PCVT_DISABLE_INTR ();
789 pcvt_timeout_scheduled = 0;
798 #ifdef _DEV_KBD_KBDREG_H_
800 detect_kbd(void *arg)
807 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
809 kbd = kbd_get_keyboard(i);
812 reset_keyboard = 1; /* ok to reset the keyboard */
817 timeout(detect_kbd, (void *)unit, hz*2);
821 pcevent(keyboard_t *thiskbd, int event, void *arg)
826 return EINVAL; /* shouldn't happen */
832 case KBDIO_UNLOADING:
835 kbd_release(thiskbd, (void *)&kbd);
836 timeout(detect_kbd, (void *)unit, hz*4);
842 #endif /* _DEV_KBD_KBDREG_H_ */
852 # if PCVT_SLOW_INTERRUPT
856 # ifdef _DEV_KBD_KBDREG_H_
860 #else /* !PCVT_KBD_FIFO */
862 #endif /* PCVT_KBD_FIFO */
866 #endif /* PCVT_SCREENSAVER */
875 # ifndef _DEV_KBD_KBDREG_H_
876 while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) /* check 8042 buffer */
878 ret = 1; /* got something */
880 PCVT_KBD_DELAY(); /* 7 us delay */
882 dt = inb(CONTROLLER_DATA); /* get it 8042 data */
884 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
886 ret = 1; /* got something */
888 # endif /* _DEV_KBD_KBDREG_H_ */
890 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
892 log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
896 pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
898 PCVT_DISABLE_INTR (); /* XXX necessary ? */
899 pcvt_kbd_count++; /* update fifo count */
902 if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
903 pcvt_kbd_wptr = 0; /* wraparound pointer */
907 if (ret == 1) /* got data from keyboard ? */
909 if (!pcvt_timeout_scheduled) /* if not already active .. */
911 PCVT_DISABLE_INTR ();
912 pcvt_timeout_scheduled = 1; /* flag active */
913 timeout(pcvt_timeout, NULL, hz / 100); /* fire off */
918 #else /* !PCVT_KBD_FIFO */
920 if((cp = sgetc(1)) == 0)
926 if(!(vs[current_video_screen].openf)) /* XXX was vs[minor(dev)] */
932 /* pass a NULL character */
933 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
936 #endif /* PCVT_NULLCHARS */
939 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
941 #endif /* PCVT_KBD_FIFO */
945 #if PCVT_NETBSD || PCVT_FREEBSD >= 200
948 pcstart(register struct tty *tp)
950 register struct clist *rbp;
952 u_char buf[PCVT_PCBURST];
956 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
959 tp->t_state |= TS_BUSY;
963 async_update(UPDATE_KERN);
968 * Call q_to_b() at spltty() to ensure that the queue is empty when
969 * the loop terminates.
974 while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
976 if(vs[minor(tp->t_dev)].scrolling)
980 * We need to do this outside spl since it could be fairly
981 * expensive and we don't want our serial ports to overflow.
984 sput(&buf[0], 0, len, minor(tp->t_dev));
988 tp->t_state &= ~TS_BUSY;
990 #ifndef TS_ASLEEP /* FreeBSD some time after 2.0.5 */
993 if (rbp->c_cc <= tp->t_lowat)
995 if (tp->t_state&TS_ASLEEP)
997 tp->t_state &= ~TS_ASLEEP;
998 wakeup((caddr_t)rbp);
1000 selwakeup(&tp->t_wsel);
1008 pcstop(struct tty *tp, int flag)
1012 #else /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1015 pcstart(struct tty *tp)
1022 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
1030 #if !(PCVT_FREEBSD > 114)
1032 #if !(PCVT_FREEBSD > 111)
1033 if (RB_LEN(&tp->t_out) <= tp->t_lowat)
1035 if (RB_LEN(tp->t_out) <= tp->t_lowat)
1038 if (tp->t_state&TS_ASLEEP)
1040 tp->t_state &= ~TS_ASLEEP;
1041 #if !(PCVT_FREEBSD > 111)
1042 wakeup((caddr_t)&tp->t_out);
1044 wakeup((caddr_t)tp->t_out);
1050 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
1052 tp->t_state &= ~TS_WCOLL;
1056 #else /* PCVT_FREEBSD > 114 */
1057 if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT)
1061 #endif /* !PCVT_FREEBSD > 114 */
1063 #if !(PCVT_FREEBSD > 111)
1064 if (RB_LEN(&tp->t_out) == 0)
1066 if (RB_LEN(tp->t_out) == 0)
1072 #if !(PCVT_FREEBSD > 111)
1073 c = getc(&tp->t_out);
1075 c = getc(tp->t_out);
1078 tp->t_state |= TS_BUSY; /* patch from Frank Maclachlan */
1080 sput(&c, 0, 1, minor(tp->t_dev));
1082 tp->t_state &= ~TS_BUSY; /* patch from Frank Maclachlan */
1088 #endif /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1090 /*---------------------------------------------------------------------------*
1092 *---------------------------------------------------------------------------*/
1094 #if !PCVT_NETBSD /* has moved to cons.c in netbsd-current */
1096 consinit() /* init for kernel messages during boot */
1099 #endif /* PCVT_NETBSD */
1101 #if PCVT_FREEBSD > 205
1106 pccnprobe(struct consdev *cp)
1111 /* See if this driver is disabled in probe hint. */
1112 if (resource_int_value("vt", unit, "disabled", &i) == 0 && i) {
1113 cp->cn_pri = CN_DEAD;
1117 #ifdef _DEV_KBD_KBDREG_H_
1118 kbd_configure(KB_CONF_PROBE_ONLY);
1119 if (kbd_find_keyboard("*", unit) < 0)
1121 cp->cn_pri = CN_DEAD;
1124 #endif /* _DEV_KBD_KBDREG_H_ */
1126 /* initialize required fields */
1128 cp->cn_dev = makedev(CDEV_MAJOR, 0);
1129 cp->cn_pri = CN_INTERNAL;
1133 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
1134 cp->cn_tp = &pccons[0];
1136 cp->cn_tp = pccons[0];
1137 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
1139 #endif /* !PCVT_NETBSD */
1141 #if PCVT_FREEBSD <= 205
1146 #if PCVT_FREEBSD > 205
1151 pccninit(struct consdev *cp)
1156 pcvt_is_console = 1;
1158 #ifdef _DEV_KBD_KBDREG_H_
1160 * Don't reset the keyboard via `kbdio' just yet.
1161 * The system clock has not been calibrated...
1167 kbd_release(kbd, (void *)&kbd);
1170 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
1172 kbd = kbd_get_keyboard(i);
1174 #if PCVT_SCANSET == 2
1176 * Turn off scancode translation early so that UserConfig
1177 * and DDB can read the keyboard.
1181 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
1182 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1183 KBD_TRANSLATION, 0);
1185 #endif /* PCVT_SCANSET == 2 */
1187 #endif /* _DEV_KBD_KBDREG_H_ */
1189 #if PCVT_FREEBSD <= 205
1195 pccnterm(struct consdev *cp)
1197 #ifdef _DEV_KBD_KBDREG_H_
1200 kbd_release(kbd, (void *)&kbd);
1203 #endif /* _DEV_KBD_KBDREG_H_ */
1206 #if PCVT_FREEBSD > 205
1211 pccnputc(Dev_t dev, U_char c)
1216 if(current_video_screen != 0)
1219 #if !PCVT_USL_VT_COMPAT
1222 switch_screen(0, 0);
1223 #endif /* !PCVT_USL_VT_COMPAT */
1227 #endif /* PCVT_SW0CNOUTP */
1230 sput("\r", 1, 1, 0);
1232 sput((char *) &c, 1, 1, 0);
1234 async_update(UPDATE_KERN);
1236 #if PCVT_FREEBSD <= 205
1245 static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
1250 #if !PCVT_USL_VT_COMPAT
1253 #else /* !PCVT_USL_VT_COMPAT */
1256 #endif /* !PCVT_USL_VT_COMPAT */
1258 #endif /* XSERVER */
1262 * We still have a pending key sequence, e.g.
1263 * from an arrow key. Deliver this one first.
1267 #ifdef _DEV_KBD_KBDREG_H_
1272 s = spltty(); /* block pcrint while we poll */
1274 #ifdef _DEV_KBD_KBDREG_H_
1275 (*kbdsw[kbd->kb_index]->enable)(kbd);
1278 #ifdef _DEV_KBD_KBDREG_H_
1279 (*kbdsw[kbd->kb_index]->disable)(kbd);
1285 /* Preserve the multi-char sequence for the next call. */
1286 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
1291 #if ! (PCVT_FREEBSD >= 201)
1292 /* this belongs to cons.c */
1295 #endif /* ! (PCVT_FREEBSD >= 201) */
1300 #if PCVT_FREEBSD >= 200
1302 pccncheckc(Dev_t dev)
1307 #ifdef _DEV_KBD_KBDREG_H_
1314 #ifdef _DEV_KBD_KBDREG_H_
1315 (*kbdsw[kbd->kb_index]->enable)(kbd);
1318 #ifdef _DEV_KBD_KBDREG_H_
1319 (*kbdsw[kbd->kb_index]->disable)(kbd);
1323 return (cp == NULL ? -1 : *cp);
1325 #endif /* PCVT_FREEBSD >= 200 */
1327 #if PCVT_NETBSD >= 100
1329 pccnpollc(Dev_t dev, int on)
1336 * If disabling polling, make sure there are no bytes left in
1337 * the FIFO, holding up the interrupt line. Otherwise we
1338 * won't get any further interrupts.
1345 #endif /* PCVT_NETBSD >= 100 */
1347 /*---------------------------------------------------------------------------*
1348 * Set line parameters
1349 *---------------------------------------------------------------------------*/
1351 pcparam(struct tty *tp, struct termios *t)
1353 register int cflag = t->c_cflag;
1355 /* and copy to tty */
1357 tp->t_ispeed = t->c_ispeed;
1358 tp->t_ospeed = t->c_ospeed;
1359 tp->t_cflag = cflag;
1364 /*----------------------------------------------------------------------*
1365 * read initial VGA palette (as stored by VGA ROM BIOS) into
1367 *----------------------------------------------------------------------*/
1371 register unsigned idx;
1372 register struct rgb *val;
1374 /* first, read all and store to first screen's save buffer */
1375 for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
1376 vgapaletteio(idx, val, 0 /* read it */);
1378 /* now, duplicate for remaining screens */
1379 for(idx = 1; idx < PCVT_NSCREENS; idx++)
1380 bcopy(vs[0].palette, vs[idx].palette,
1381 NVGAPEL * sizeof(struct rgb));
1384 #if defined XSERVER && !PCVT_USL_VT_COMPAT
1385 /*----------------------------------------------------------------------*
1386 * initialize for X mode
1387 * i.e.: grant current process (the X server) all IO privileges,
1388 * and mark in static variable so other hooks can test for it,
1389 * save all loaded fonts and screen pages to pageable buffers;
1390 * if parameter `on' is false, the same procedure is done reverse.
1391 *----------------------------------------------------------------------*/
1393 pcvt_xmode_set(int on, struct proc *p)
1395 static unsigned char *saved_fonts[NVGAFONTS];
1397 #if PCVT_SCREENSAVER
1398 static unsigned saved_scrnsv_tmo = 0;
1399 #endif /* PCVT_SCREENSAVER */
1401 #if (PCVT_NETBSD > 9) || (PCVT_FREEBSD > 102)
1402 struct trapframe *fp;
1404 struct syscframe *fp;
1405 #endif /* PCVT_NETBSD > 9 */
1409 /* X will only run on VGA and Hercules adaptors */
1411 if(adaptor_type != VGA_ADAPTOR && adaptor_type != MDA_ADAPTOR)
1415 fp = (struct trapframe *)p->p_regs;
1417 fp = (struct syscframe *)p->p_regs;
1418 #endif /* PCVT_NETBSD > 9 */
1423 * Test whether the calling process has super-user privileges
1424 * and we're in insecure mode.
1425 * This prevents us from granting the potential security hole
1426 * `IO priv' to insufficiently privileged processes.
1431 if (securelevel > 0)
1437 pcvt_xmode = pcvt_kbd_raw = 1;
1439 for(i = 0; i < totalfonts; i++)
1443 saved_fonts[i] = (unsigned char *)
1444 malloc(32 * 256, M_DEVBUF, M_WAITOK);
1445 if(saved_fonts[i] == 0)
1448 "pcvt_xmode_set: no font buffer available\n");
1453 vga_move_charset(i, saved_fonts[i], 1);
1462 #if PCVT_SCREENSAVER
1463 if(saved_scrnsv_tmo = scrnsv_timeout)
1464 pcvt_set_scrnsv_tmo(0); /* turn it off */
1465 #endif /* PCVT_SCREENSAVER */
1467 async_update(UPDATE_STOP); /* turn off */
1469 /* disable text output and save screen contents */
1470 /* video board memory -> kernel memory */
1472 bcopy(vsp->Crtat, vsp->Memory,
1473 vsp->screen_rowsize * vsp->maxcol * CHR);
1475 vsp->Crtat = vsp->Memory; /* operate in memory now */
1477 #ifndef _DEV_KBD_KBDREG_H_
1479 #if PCVT_SCANSET == 2
1480 /* put keyboard to return ancient PC scan codes */
1481 kbc_8042cmd(CONTR_WRITE);
1482 #if PCVT_USEKBDSEC /* security enabled */
1483 outb(CONTROLLER_DATA,
1484 (COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1485 #else /* security disabled */
1486 outb(CONTROLLER_DATA,
1487 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1488 #endif /* PCVT_USEKBDSEC */
1489 #endif /* PCVT_SCANSET == 2 */
1491 #else /* _DEV_KBD_KBDREG_H_ */
1493 #if PCVT_SCANSET == 2
1494 /* put keyboard to return ancient PC scan codes */
1495 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1496 KBD_TRANSLATION, KBD_TRANSLATION);
1497 #endif /* PCVT_SCANSET == 2 */
1499 #endif /* !_DEV_KBD_KBDREG_H_ */
1502 fp->tf_eflags |= PSL_IOPL;
1504 fp->sf_eflags |= PSL_IOPL;
1505 #endif /* PCVT_NETBSD > 9 */
1510 if(!pcvt_xmode) /* verify if in X */
1513 pcvt_xmode = pcvt_kbd_raw = 0;
1515 for(i = 0; i < totalfonts; i++)
1519 vga_move_charset(i, saved_fonts[i], 0);
1520 free(saved_fonts[i], M_DEVBUF);
1526 fp->tf_eflags &= ~PSL_IOPL;
1528 fp->sf_eflags &= ~PSL_IOPL;
1529 #endif /* PCVT_NETBSD > 9 */
1531 #if PCVT_SCREENSAVER
1532 if(saved_scrnsv_tmo)
1533 pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);
1534 #endif /* PCVT_SCREENSAVER */
1536 #ifndef _DEV_KBD_KBDREG_H_
1538 #if PCVT_SCANSET == 2
1539 kbc_8042cmd(CONTR_WRITE);
1540 #if PCVT_USEKBDSEC /* security enabled */
1541 outb(CONTROLLER_DATA,
1542 (COMMAND_SYSFLG|COMMAND_IRQEN));
1543 #else /* security disabled */
1544 outb(CONTROLLER_DATA,
1545 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN));
1546 #endif /* PCVT_USEKBDSEC */
1547 #endif /* PCVT_SCANSET == 2 */
1549 #else /* _DEV_KBD_KBDREG_H_ */
1551 #if PCVT_SCANSET == 2
1552 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1553 KBD_TRANSLATION, 0);
1554 #endif /* PCVT_SCANSET == 2 */
1556 #endif /* !_DEV_KBD_KBDREG_H_ */
1558 if(adaptor_type == MDA_ADAPTOR)
1561 * Due to the fact that HGC registers are write-only,
1562 * the Xserver can only make guesses about the state
1563 * the HGC adaptor has been before turning on X mode.
1564 * Thus, the display must be re-enabled now, and the
1565 * cursor shape and location restored.
1567 outb(GN_DMCNTLM, 0x28); /* enable display, text mode */
1568 outb(addr_6845, CRTC_CURSORH); /* select high register */
1570 ((vsp->Crtat + vsp->cur_offset) - Crtat) >> 8);
1571 outb(addr_6845, CRTC_CURSORL); /* select low register */
1573 ((vsp->Crtat + vsp->cur_offset) - Crtat));
1575 outb(addr_6845, CRTC_CURSTART); /* select high register */
1576 outb(addr_6845+1, vsp->cursor_start);
1577 outb(addr_6845, CRTC_CUREND); /* select low register */
1578 outb(addr_6845+1, vsp->cursor_end);
1581 /* restore screen and re-enable text output */
1582 /* kernel memory -> video board memory */
1584 bcopy(vsp->Memory, Crtat,
1585 vsp->screen_rowsize * vsp->maxcol * CHR);
1587 vsp->Crtat = Crtat; /* operate on-screen now */
1589 /* set crtc screen memory start address */
1591 outb(addr_6845, CRTC_STARTADRH);
1592 outb(addr_6845+1, (vsp->Crtat - Crtat) >> 8);
1593 outb(addr_6845, CRTC_STARTADRL);
1594 outb(addr_6845+1, (vsp->Crtat - Crtat));
1596 async_update(UPDATE_START);
1600 #endif /* XSERVER && !PCVT_USL_VT_COMPAT */
1602 #endif /* NVT > 0 */
1604 /*-------------------------- E O F -------------------------------------*/