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.11 2004/09/18 20:23:04 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 */
183 vt_coldmalloc(); /* allocate memory for screens */
185 #ifdef _DEV_KBD_KBDREG_H_
187 timeout(detect_kbd, (void *)dev->id_unit, hz*2);
188 #endif /* _DEV_KBD_KBDREG_H_ */
190 #if PCVT_NETBSD || PCVT_FREEBSD
195 printf("vt%d: ", dev->id_unit);
196 #endif /* PCVT_NETBSD > 9 */
213 printf("%s, ", (char *)vga_string(vga_type));
215 printf("80/132 col");
231 printf(", %d scr, ", totalscreens);
233 switch(keyboard_type)
248 printf("kbd, [R%s]\n", PCVT_REL);
250 #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
252 for(i = 0; i < totalscreens; i++)
256 pc_tty[i] = ttymalloc();
257 vs[i].vs_tty = pc_tty[i];
258 #else /* !PCVT_NETBSD */
259 pccons[i] = ttymalloc(pccons[i]);
260 vs[i].vs_tty = pccons[i];
261 #endif /* PCVT_NETBSD */
267 pc_tty[totalscreens] = ttymalloc(); /* the mouse emulator tty */
268 #else /* !PCVT_NETBSD */
269 /* the mouse emulator tty */
270 pc_tty[totalscreens] = ttymalloc(pccons[totalscreens]);
271 #endif /* PCVT_NETBSD */
272 #endif /* PCVT_EMU_MOUSE */
276 #else /* !PCVT_NETBSD */
278 #endif /* PCVT_NETBSD */
280 #endif /* #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
282 #else /* !PCVT_NETBSD && !PCVT_FREEBSD*/
299 printf(" <%s,", (char *)vga_string(vga_type));
301 printf("80/132 col");
317 printf(",%d scr,", totalscreens);
319 switch(keyboard_type)
334 printf("kbd,[R%s]>", PCVT_REL);
336 #endif /* PCVT_NETBSD || PCVT_FREEBSD */
338 #if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
339 cdevsw_add(&pc_cdevsw, 0, 0);
340 for(i = 0; i < totalscreens; i++)
342 ttyregister(&pccons[i]);
343 vs[i].vs_tty = &pccons[i];
344 make_dev(&pc_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
346 #endif /* !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
348 async_update(UPDATE_START); /* start asynchronous updates */
352 vthand.ih_fun = pcrint;
354 vthand.ih_level = IPL_TTY;
356 #if (PCVT_NETBSD > 100) && defined(IST_EDGE)
357 intr_establish(ia->ia_irq, IST_EDGE, &vthand);
358 #else /* PCVT_NETBSD > 100 */
359 intr_establish(ia->ia_irq, &vthand);
360 #endif /* PCVT_NETBSD > 100 */
362 #else /* PCVT_NETBSD > 9 */
364 dev->id_ointr = pcrint;
368 #endif /* PCVT_NETBSD > 9 */
372 /* had a look at the friedl driver */
377 get_pccons(Dev_t dev)
382 if(i == totalscreens)
383 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
387 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
388 #endif /* PCVT_EMU_MOUSE */
390 if(i >= PCVT_NSCREENS)
392 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
402 get_pccons(Dev_t dev)
407 if(i == totalscreens)
409 #endif /* PCVT_EMU_MOUSE */
411 if(i >= PCVT_NSCREENS)
416 #endif /* !PCVT_NETBSD */
418 /*---------------------------------------------------------------------------*
419 * /dev/ttyc0, /dev/ttyc1, etc.
420 *---------------------------------------------------------------------------*/
422 pcopen(Dev_t dev, int flag, int mode, struct thread *td)
425 struct video_state *vsx;
431 if(i == totalscreens)
434 #endif /* PCVT_EMU_MOUSE */
438 if((tp = get_pccons(dev)) == NULL)
444 if(i == totalscreens)
446 if(mouse.opened == 0)
447 mouse.buttons = mouse.extendedseen =
448 mouse.breakseen = mouse.lastmove.tv_sec = 0;
453 #endif /* PCVT_EMU_MOUSE */
457 tp->t_oproc = pcstart;
458 tp->t_param = pcparam;
459 tp->t_stop = nottystop;
462 if ((tp->t_state & TS_ISOPEN) == 0)
465 #ifdef TS_WOPEN /* not (FreeBSD-1.1.5 or FreeBSD some time after 2.0.5) */
466 tp->t_state |= TS_WOPEN;
470 tp->t_iflag = TTYDEF_IFLAG;
471 tp->t_oflag = TTYDEF_OFLAG;
472 tp->t_cflag = TTYDEF_CFLAG;
473 tp->t_lflag = TTYDEF_LFLAG;
474 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
475 pcparam(tp, &tp->t_termios);
476 (*linesw[tp->t_line].l_modem)(tp, 1); /* fake connection */
477 winsz = 1; /* set winsize later */
479 else if (tp->t_state & TS_XCLUDE && suser(td))
482 #if PCVT_NETBSD || (PCVT_FREEBSD >= 200)
483 retval = ((*linesw[tp->t_line].l_open)(dev, tp));
485 retval = ((*linesw[tp->t_line].l_open)(dev, tp, flag));
486 #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */
492 * The line discipline has clobbered t_winsize if TS_ISOPEN
493 * was clear. (NetBSD PR #400 from Bill Sommerfeld)
494 * We have to do this after calling the open routine, because
495 * it does some other things in other/older *BSD releases -hm
500 tp->t_winsize.ws_col = vsx->maxcol;
501 tp->t_winsize.ws_row = vsx->screen_rows;
502 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
503 tp->t_winsize.ws_ypixel = 400;
512 pcclose(Dev_t dev, int flag, int mode, struct thread *td)
515 struct video_state *vsx;
519 if(i == totalscreens)
522 #endif /* PCVT_EMU_MOUSE */
526 if((tp = get_pccons(dev)) == NULL)
529 (*linesw[tp->t_line].l_close)(tp, flag);
533 if(i == totalscreens)
536 #endif /* PCVT_EMU_MOUSE */
540 #if PCVT_USL_VT_COMPAT
543 if(i == totalscreens)
546 #endif /* PCVT_EMU_MOUSE */
548 reset_usl_modes(vsx);
550 #endif /* PCVT_USL_VT_COMPAT */
556 pcioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
561 if((tp = get_pccons(dev)) == NULL)
564 /* note that some ioctl's are global, e.g. KBSTPMAT: There is
565 * only one keyboard and different repeat rates for instance between
566 * sessions are a suspicious wish. If you really need this make the
567 * appropriate variables arrays
571 if(minor(dev) == totalscreens)
573 if((error = mouse_ioctl(dev, cmd, data)) >= 0)
577 #endif /* PCVT_EMU_MOUSE */
580 #if PCVT_USL_VT_COMPAT
582 if((error = usl_vt_ioctl(dev, cmd, data, flag, td->td_proc)) >= 0)
586 * just for compatibility:
587 * XFree86 < 2.0 and SuperProbe still might use it
589 * NB: THIS IS A HACK! Do not use it unless you explicitly need.
590 * Especially, since the vty is not put into process-controlled
591 * mode (this would require the application to co-operate), any
592 * attempts to switch vtys while this kind of X mode is active
593 * may cause serious trouble.
597 case CONSOLE_X_MODE_ON:
601 if((error = usl_vt_ioctl(dev, KDENABIO, 0, flag, td->td_proc)) > 0)
605 if((error = usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, td->td_proc))
610 error = usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, td->td_proc);
614 case CONSOLE_X_MODE_OFF:
618 (void)usl_vt_ioctl(dev, KDDISABIO, 0, flag, td->td_proc);
621 (void)usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, td->td_proc);
624 (void)usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, td->td_proc);
632 * If `data' is non-null, the first int value denotes
633 * the pitch, the second a duration. Otherwise, behaves
641 sysbeep(((int *)data)[0],
642 ((int *)data)[1] * hz / 1000);
643 #else /* PCVT_NETBSD */
644 sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
645 ((int *)data)[1] * hz / 3000);
646 #endif /* PCVT_NETBSD */
651 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
655 default: /* fall through */ ;
658 #else /* PCVT_USL_VT_COMPAT */
662 case CONSOLE_X_MODE_ON:
663 return pcvt_xmode_set(1, td->td_proc);
665 case CONSOLE_X_MODE_OFF:
666 return pcvt_xmode_set(0, td->td_proc);
671 * If `data' is non-null, the first int value denotes
672 * the pitch, the second a duration. Otherwise, behaves
680 sysbeep(((int *)data)[0],
681 ((int *)data)[1] * hz / 1000);
682 #else /* PCVT_NETBSD */
683 sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
684 ((int *)data)[1] * hz / 3000);
685 #endif /* PCVT_NETBSD */
690 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
694 default: /* fall through */ ;
697 #endif /* PCVT_USL_VT_COMPAT */
700 if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
703 if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
710 #if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
711 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td))
715 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag)) >= 0)
717 #endif /* PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 */
720 if((error = ttioctl(tp, cmd, data, flag, td)) >= 0)
723 if((error = ttioctl(tp, cmd, data, flag)) != ENOIOCTL)
725 #endif /* PCVT_NETBSD > 9 */
731 pcmmap(Dev_t dev, vm_offset_t offset, int nprot)
733 if (offset > 0x20000 - PAGE_SIZE)
735 return i386_btop((0xa0000 + offset));
738 /*---------------------------------------------------------------------------*
740 * handle a keyboard receive interrupt
742 * NOTE: the keyboard is multiplexed by means of "pcconsp"
743 * between virtual screens. pcconsp - switching is done in
744 * the vgapage() routine
746 *---------------------------------------------------------------------------*/
750 u_char pcvt_kbd_fifo[PCVT_KBD_FIFO_SZ];
751 static int pcvt_kbd_wptr = 0;
752 int pcvt_kbd_rptr = 0;
753 short pcvt_kbd_count= 0;
754 static u_char pcvt_timeout_scheduled = 0;
757 pcvt_timeout(void *arg)
761 #if PCVT_SLOW_INTERRUPT
765 pcvt_timeout_scheduled = 0;
769 #endif /* PCVT_SCREENSAVER */
771 while (pcvt_kbd_count)
773 if (((cp = sgetc(1)) != 0) &&
774 (vs[current_video_screen].openf))
780 /* pass a NULL character */
781 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
784 #endif /* PCVT_NULLCHARS */
787 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
790 PCVT_DISABLE_INTR ();
793 pcvt_timeout_scheduled = 0;
802 #ifdef _DEV_KBD_KBDREG_H_
804 detect_kbd(void *arg)
811 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
813 kbd = kbd_get_keyboard(i);
816 reset_keyboard = 1; /* ok to reset the keyboard */
821 timeout(detect_kbd, (void *)unit, hz*2);
825 pcevent(keyboard_t *thiskbd, int event, void *arg)
830 return EINVAL; /* shouldn't happen */
836 case KBDIO_UNLOADING:
839 kbd_release(thiskbd, (void *)&kbd);
840 timeout(detect_kbd, (void *)unit, hz*4);
846 #endif /* _DEV_KBD_KBDREG_H_ */
856 # if PCVT_SLOW_INTERRUPT
860 # ifdef _DEV_KBD_KBDREG_H_
864 #else /* !PCVT_KBD_FIFO */
866 #endif /* PCVT_KBD_FIFO */
870 #endif /* PCVT_SCREENSAVER */
879 # ifndef _DEV_KBD_KBDREG_H_
880 while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) /* check 8042 buffer */
882 ret = 1; /* got something */
884 PCVT_KBD_DELAY(); /* 7 us delay */
886 dt = inb(CONTROLLER_DATA); /* get it 8042 data */
888 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
890 ret = 1; /* got something */
892 # endif /* _DEV_KBD_KBDREG_H_ */
894 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
896 log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
900 pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
902 PCVT_DISABLE_INTR (); /* XXX necessary ? */
903 pcvt_kbd_count++; /* update fifo count */
906 if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
907 pcvt_kbd_wptr = 0; /* wraparound pointer */
911 if (ret == 1) /* got data from keyboard ? */
913 if (!pcvt_timeout_scheduled) /* if not already active .. */
915 PCVT_DISABLE_INTR ();
916 pcvt_timeout_scheduled = 1; /* flag active */
917 timeout(pcvt_timeout, NULL, hz / 100); /* fire off */
922 #else /* !PCVT_KBD_FIFO */
924 if((cp = sgetc(1)) == 0)
930 if(!(vs[current_video_screen].openf)) /* XXX was vs[minor(dev)] */
936 /* pass a NULL character */
937 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
940 #endif /* PCVT_NULLCHARS */
943 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
945 #endif /* PCVT_KBD_FIFO */
949 #if PCVT_NETBSD || PCVT_FREEBSD >= 200
952 pcstart(struct tty *tp)
956 u_char buf[PCVT_PCBURST];
960 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
963 tp->t_state |= TS_BUSY;
967 async_update(UPDATE_KERN);
972 * Call q_to_b() at spltty() to ensure that the queue is empty when
973 * the loop terminates.
978 while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
980 if(vs[minor(tp->t_dev)].scrolling)
984 * We need to do this outside spl since it could be fairly
985 * expensive and we don't want our serial ports to overflow.
988 sput(&buf[0], 0, len, minor(tp->t_dev));
992 tp->t_state &= ~TS_BUSY;
994 #ifndef TS_ASLEEP /* FreeBSD some time after 2.0.5 */
997 if (rbp->c_cc <= tp->t_lowat)
999 if (tp->t_state&TS_ASLEEP)
1001 tp->t_state &= ~TS_ASLEEP;
1002 wakeup((caddr_t)rbp);
1004 selwakeup(&tp->t_wsel);
1012 pcstop(struct tty *tp, int flag)
1016 #else /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1019 pcstart(struct tty *tp)
1026 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
1034 #if !(PCVT_FREEBSD > 114)
1036 #if !(PCVT_FREEBSD > 111)
1037 if (RB_LEN(&tp->t_out) <= tp->t_lowat)
1039 if (RB_LEN(tp->t_out) <= tp->t_lowat)
1042 if (tp->t_state&TS_ASLEEP)
1044 tp->t_state &= ~TS_ASLEEP;
1045 #if !(PCVT_FREEBSD > 111)
1046 wakeup((caddr_t)&tp->t_out);
1048 wakeup((caddr_t)tp->t_out);
1054 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
1056 tp->t_state &= ~TS_WCOLL;
1060 #else /* PCVT_FREEBSD > 114 */
1061 if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT)
1065 #endif /* !PCVT_FREEBSD > 114 */
1067 #if !(PCVT_FREEBSD > 111)
1068 if (RB_LEN(&tp->t_out) == 0)
1070 if (RB_LEN(tp->t_out) == 0)
1076 #if !(PCVT_FREEBSD > 111)
1077 c = getc(&tp->t_out);
1079 c = getc(tp->t_out);
1082 tp->t_state |= TS_BUSY; /* patch from Frank Maclachlan */
1084 sput(&c, 0, 1, minor(tp->t_dev));
1086 tp->t_state &= ~TS_BUSY; /* patch from Frank Maclachlan */
1092 #endif /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1094 /*---------------------------------------------------------------------------*
1096 *---------------------------------------------------------------------------*/
1098 #if !PCVT_NETBSD /* has moved to cons.c in netbsd-current */
1100 consinit() /* init for kernel messages during boot */
1103 #endif /* PCVT_NETBSD */
1105 #if PCVT_FREEBSD > 205
1110 pccnprobe(struct consdev *cp)
1115 /* See if this driver is disabled in probe hint. */
1116 if (resource_int_value("vt", unit, "disabled", &i) == 0 && i) {
1117 cp->cn_pri = CN_DEAD;
1121 #ifdef _DEV_KBD_KBDREG_H_
1122 kbd_configure(KB_CONF_PROBE_ONLY);
1123 if (kbd_find_keyboard("*", unit) < 0)
1125 cp->cn_pri = CN_DEAD;
1128 #endif /* _DEV_KBD_KBDREG_H_ */
1130 /* initialize required fields */
1132 cp->cn_dev = make_adhoc_dev(&pc_cdevsw, 0);
1133 cp->cn_pri = CN_INTERNAL;
1137 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
1138 cp->cn_tp = &pccons[0];
1140 cp->cn_tp = pccons[0];
1141 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
1143 #endif /* !PCVT_NETBSD */
1145 #if PCVT_FREEBSD <= 205
1150 #if PCVT_FREEBSD > 205
1155 pccninit(struct consdev *cp)
1160 pcvt_is_console = 1;
1162 #ifdef _DEV_KBD_KBDREG_H_
1164 * Don't reset the keyboard via `kbdio' just yet.
1165 * The system clock has not been calibrated...
1171 kbd_release(kbd, (void *)&kbd);
1174 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
1176 kbd = kbd_get_keyboard(i);
1178 #if PCVT_SCANSET == 2
1180 * Turn off scancode translation early so that UserConfig
1181 * and DDB can read the keyboard.
1185 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
1186 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1187 KBD_TRANSLATION, 0);
1189 #endif /* PCVT_SCANSET == 2 */
1191 #endif /* _DEV_KBD_KBDREG_H_ */
1193 #if PCVT_FREEBSD <= 205
1199 pccnterm(struct consdev *cp)
1201 #ifdef _DEV_KBD_KBDREG_H_
1204 kbd_release(kbd, (void *)&kbd);
1207 #endif /* _DEV_KBD_KBDREG_H_ */
1210 #if PCVT_FREEBSD > 205
1215 pccnputc(Dev_t dev, U_char c)
1220 if(current_video_screen != 0)
1223 #if !PCVT_USL_VT_COMPAT
1226 switch_screen(0, 0);
1227 #endif /* !PCVT_USL_VT_COMPAT */
1231 #endif /* PCVT_SW0CNOUTP */
1234 sput("\r", 1, 1, 0);
1236 sput((char *) &c, 1, 1, 0);
1238 async_update(UPDATE_KERN);
1240 #if PCVT_FREEBSD <= 205
1249 static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
1254 #if !PCVT_USL_VT_COMPAT
1257 #else /* !PCVT_USL_VT_COMPAT */
1260 #endif /* !PCVT_USL_VT_COMPAT */
1262 #endif /* XSERVER */
1266 * We still have a pending key sequence, e.g.
1267 * from an arrow key. Deliver this one first.
1271 #ifdef _DEV_KBD_KBDREG_H_
1276 s = spltty(); /* block pcrint while we poll */
1278 #ifdef _DEV_KBD_KBDREG_H_
1279 (*kbdsw[kbd->kb_index]->enable)(kbd);
1282 #ifdef _DEV_KBD_KBDREG_H_
1283 (*kbdsw[kbd->kb_index]->disable)(kbd);
1289 /* Preserve the multi-char sequence for the next call. */
1290 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
1295 #if ! (PCVT_FREEBSD >= 201)
1296 /* this belongs to cons.c */
1299 #endif /* ! (PCVT_FREEBSD >= 201) */
1304 #if PCVT_FREEBSD >= 200
1306 pccncheckc(Dev_t dev)
1311 #ifdef _DEV_KBD_KBDREG_H_
1318 #ifdef _DEV_KBD_KBDREG_H_
1319 (*kbdsw[kbd->kb_index]->enable)(kbd);
1322 #ifdef _DEV_KBD_KBDREG_H_
1323 (*kbdsw[kbd->kb_index]->disable)(kbd);
1327 return (cp == NULL ? -1 : *cp);
1329 #endif /* PCVT_FREEBSD >= 200 */
1331 #if PCVT_NETBSD >= 100
1333 pccnpollc(Dev_t dev, int on)
1340 * If disabling polling, make sure there are no bytes left in
1341 * the FIFO, holding up the interrupt line. Otherwise we
1342 * won't get any further interrupts.
1349 #endif /* PCVT_NETBSD >= 100 */
1351 /*---------------------------------------------------------------------------*
1352 * Set line parameters
1353 *---------------------------------------------------------------------------*/
1355 pcparam(struct tty *tp, struct termios *t)
1357 int cflag = t->c_cflag;
1359 /* and copy to tty */
1361 tp->t_ispeed = t->c_ispeed;
1362 tp->t_ospeed = t->c_ospeed;
1363 tp->t_cflag = cflag;
1368 /*----------------------------------------------------------------------*
1369 * read initial VGA palette (as stored by VGA ROM BIOS) into
1371 *----------------------------------------------------------------------*/
1378 /* first, read all and store to first screen's save buffer */
1379 for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
1380 vgapaletteio(idx, val, 0 /* read it */);
1382 /* now, duplicate for remaining screens */
1383 for(idx = 1; idx < PCVT_NSCREENS; idx++)
1384 bcopy(vs[0].palette, vs[idx].palette,
1385 NVGAPEL * sizeof(struct rgb));
1388 #if defined XSERVER && !PCVT_USL_VT_COMPAT
1389 /*----------------------------------------------------------------------*
1390 * initialize for X mode
1391 * i.e.: grant current process (the X server) all IO privileges,
1392 * and mark in static variable so other hooks can test for it,
1393 * save all loaded fonts and screen pages to pageable buffers;
1394 * if parameter `on' is false, the same procedure is done reverse.
1395 *----------------------------------------------------------------------*/
1397 pcvt_xmode_set(int on, struct thread *td)
1399 static unsigned char *saved_fonts[NVGAFONTS];
1401 #if PCVT_SCREENSAVER
1402 static unsigned saved_scrnsv_tmo = 0;
1403 #endif /* PCVT_SCREENSAVER */
1405 #if (PCVT_NETBSD > 9) || (PCVT_FREEBSD > 102)
1406 struct trapframe *fp;
1408 struct syscframe *fp;
1409 #endif /* PCVT_NETBSD > 9 */
1413 /* X will only run on VGA and Hercules adaptors */
1415 if(adaptor_type != VGA_ADAPTOR && adaptor_type != MDA_ADAPTOR)
1419 fp = (struct trapframe *)p->p_regs;
1421 fp = (struct syscframe *)p->p_regs;
1422 #endif /* PCVT_NETBSD > 9 */
1427 * Test whether the calling process has super-user privileges
1428 * and we're in insecure mode.
1429 * This prevents us from granting the potential security hole
1430 * `IO priv' to insufficiently privileged processes.
1435 if (securelevel > 0)
1441 pcvt_xmode = pcvt_kbd_raw = 1;
1443 for(i = 0; i < totalfonts; i++)
1447 saved_fonts[i] = (unsigned char *)
1448 malloc(32 * 256, M_DEVBUF, M_WAITOK);
1449 if(saved_fonts[i] == 0)
1452 "pcvt_xmode_set: no font buffer available\n");
1457 vga_move_charset(i, saved_fonts[i], 1);
1466 #if PCVT_SCREENSAVER
1467 if(saved_scrnsv_tmo = scrnsv_timeout)
1468 pcvt_set_scrnsv_tmo(0); /* turn it off */
1469 #endif /* PCVT_SCREENSAVER */
1471 async_update(UPDATE_STOP); /* turn off */
1473 /* disable text output and save screen contents */
1474 /* video board memory -> kernel memory */
1476 bcopy(vsp->Crtat, vsp->Memory,
1477 vsp->screen_rowsize * vsp->maxcol * CHR);
1479 vsp->Crtat = vsp->Memory; /* operate in memory now */
1481 #ifndef _DEV_KBD_KBDREG_H_
1483 #if PCVT_SCANSET == 2
1484 /* put keyboard to return ancient PC scan codes */
1485 kbc_8042cmd(CONTR_WRITE);
1486 #if PCVT_USEKBDSEC /* security enabled */
1487 outb(CONTROLLER_DATA,
1488 (COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1489 #else /* security disabled */
1490 outb(CONTROLLER_DATA,
1491 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1492 #endif /* PCVT_USEKBDSEC */
1493 #endif /* PCVT_SCANSET == 2 */
1495 #else /* _DEV_KBD_KBDREG_H_ */
1497 #if PCVT_SCANSET == 2
1498 /* put keyboard to return ancient PC scan codes */
1499 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1500 KBD_TRANSLATION, KBD_TRANSLATION);
1501 #endif /* PCVT_SCANSET == 2 */
1503 #endif /* !_DEV_KBD_KBDREG_H_ */
1506 fp->tf_eflags |= PSL_IOPL;
1508 fp->sf_eflags |= PSL_IOPL;
1509 #endif /* PCVT_NETBSD > 9 */
1514 if(!pcvt_xmode) /* verify if in X */
1517 pcvt_xmode = pcvt_kbd_raw = 0;
1519 for(i = 0; i < totalfonts; i++)
1523 vga_move_charset(i, saved_fonts[i], 0);
1524 free(saved_fonts[i], M_DEVBUF);
1530 fp->tf_eflags &= ~PSL_IOPL;
1532 fp->sf_eflags &= ~PSL_IOPL;
1533 #endif /* PCVT_NETBSD > 9 */
1535 #if PCVT_SCREENSAVER
1536 if(saved_scrnsv_tmo)
1537 pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);
1538 #endif /* PCVT_SCREENSAVER */
1540 #ifndef _DEV_KBD_KBDREG_H_
1542 #if PCVT_SCANSET == 2
1543 kbc_8042cmd(CONTR_WRITE);
1544 #if PCVT_USEKBDSEC /* security enabled */
1545 outb(CONTROLLER_DATA,
1546 (COMMAND_SYSFLG|COMMAND_IRQEN));
1547 #else /* security disabled */
1548 outb(CONTROLLER_DATA,
1549 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN));
1550 #endif /* PCVT_USEKBDSEC */
1551 #endif /* PCVT_SCANSET == 2 */
1553 #else /* _DEV_KBD_KBDREG_H_ */
1555 #if PCVT_SCANSET == 2
1556 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1557 KBD_TRANSLATION, 0);
1558 #endif /* PCVT_SCANSET == 2 */
1560 #endif /* !_DEV_KBD_KBDREG_H_ */
1562 if(adaptor_type == MDA_ADAPTOR)
1565 * Due to the fact that HGC registers are write-only,
1566 * the Xserver can only make guesses about the state
1567 * the HGC adaptor has been before turning on X mode.
1568 * Thus, the display must be re-enabled now, and the
1569 * cursor shape and location restored.
1571 outb(GN_DMCNTLM, 0x28); /* enable display, text mode */
1572 outb(addr_6845, CRTC_CURSORH); /* select high register */
1574 ((vsp->Crtat + vsp->cur_offset) - Crtat) >> 8);
1575 outb(addr_6845, CRTC_CURSORL); /* select low register */
1577 ((vsp->Crtat + vsp->cur_offset) - Crtat));
1579 outb(addr_6845, CRTC_CURSTART); /* select high register */
1580 outb(addr_6845+1, vsp->cursor_start);
1581 outb(addr_6845, CRTC_CUREND); /* select low register */
1582 outb(addr_6845+1, vsp->cursor_end);
1585 /* restore screen and re-enable text output */
1586 /* kernel memory -> video board memory */
1588 bcopy(vsp->Memory, Crtat,
1589 vsp->screen_rowsize * vsp->maxcol * CHR);
1591 vsp->Crtat = Crtat; /* operate on-screen now */
1593 /* set crtc screen memory start address */
1595 outb(addr_6845, CRTC_STARTADRH);
1596 outb(addr_6845+1, (vsp->Crtat - Crtat) >> 8);
1597 outb(addr_6845, CRTC_STARTADRL);
1598 outb(addr_6845+1, (vsp->Crtat - Crtat));
1600 async_update(UPDATE_START);
1604 #endif /* XSERVER && !PCVT_USL_VT_COMPAT */
1606 #endif /* NVT > 0 */
1608 /*-------------------------- E O F -------------------------------------*/