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 $
55 *---------------------------------------------------------------------------*/
60 #define EXTERN /* allocate mem */
62 #include <i386/isa/pcvt/pcvt_hdr.h> /* global include */
64 #if PCVT_FREEBSD >= 200
66 #include <machine/stdarg.h>
68 #include "machine/stdarg.h"
71 extern int getchar __P((void));
74 extern u_short *Crtat;
75 #endif /* PCVT_NETBSD */
77 static void vgapelinit(void); /* read initial VGA DAC palette */
79 #if defined XSERVER && !PCVT_USL_VT_COMPAT
80 static int pcvt_xmode_set(int on, struct proc *p); /* initialize for X mode */
81 #endif /* XSERVER && !PCVT_USL_VT_COMPAT */
83 #ifdef _DEV_KBD_KBDREG_H_
84 static void detect_kbd(void *arg);
85 static kbd_callback_func_t pcevent;
88 static cn_probe_t pccnprobe;
89 static cn_init_t pccninit;
90 static cn_term_t pccnterm;
91 static cn_getc_t pccngetc;
92 static cn_checkc_t pccncheckc;
93 static cn_putc_t pccnputc;
95 CONS_DRIVER(pc, pccnprobe, pccninit, pccnterm, pccngetc, pccncheckc, pccnputc,
98 static d_open_t pcopen;
99 static d_close_t pcclose;
100 static d_ioctl_t pcioctl;
101 static d_mmap_t pcmmap;
103 #define CDEV_MAJOR 12
104 static struct cdevsw pc_cdevsw = {
108 /* write */ ttywrite,
112 /* strategy */ nostrategy,
114 /* maj */ CDEV_MAJOR,
117 /* flags */ D_TTY | D_KQFILTER,
119 /* kqfilter */ ttykqfilter,
122 #if PCVT_NETBSD > 100 /* NetBSD-current Feb 20 1995 */
124 pcprobe(struct device *parent, void *match, void *aux)
128 pcprobe(struct device *parent, struct device *self, void *aux)
131 pcprobe(struct isa_device *dev)
132 #endif /* PCVT_NETBSD > 9 */
133 #endif /* PCVT_NETBSD > 100 */
135 #ifdef _DEV_KBD_KBDREG_H_
140 kbd_configure(KB_CONF_PROBE_ONLY);
141 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)dev->id_unit);
142 if ((i < 0) || ((kbd = kbd_get_keyboard(i)) == NULL))
145 reset_keyboard = 1; /* it's now safe to do kbd reset */
146 #endif /* _DEV_KBD_KBDREG_H_ */
151 ((struct isa_attach_args *)aux)->ia_iosize = 16;
154 #ifdef _DEV_KBD_KBDREG_H_
156 #elif PCVT_NETBSD || PCVT_FREEBSD
160 #endif /* PCVT_NETBSD || PCVT_FREEBSD */
161 #endif /* PCVT_NETBSD > 9 */
167 pcattach(struct device *parent, struct device *self, void *aux)
169 struct isa_attach_args *ia = aux;
170 static struct intrhand vthand;
173 pcattach(struct isa_device *dev)
175 #endif /* PCVT_NETBSD > 9 */
179 vt_coldmalloc(); /* allocate memory for screens */
181 #ifdef _DEV_KBD_KBDREG_H_
183 timeout(detect_kbd, (void *)dev->id_unit, hz*2);
184 #endif /* _DEV_KBD_KBDREG_H_ */
186 #if PCVT_NETBSD || PCVT_FREEBSD
191 printf("vt%d: ", dev->id_unit);
192 #endif /* PCVT_NETBSD > 9 */
209 printf("%s, ", (char *)vga_string(vga_type));
211 printf("80/132 col");
227 printf(", %d scr, ", totalscreens);
229 switch(keyboard_type)
244 printf("kbd, [R%s]\n", PCVT_REL);
246 #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
248 for(i = 0; i < totalscreens; i++)
252 pc_tty[i] = ttymalloc();
253 vs[i].vs_tty = pc_tty[i];
254 #else /* !PCVT_NETBSD */
255 pccons[i] = ttymalloc(pccons[i]);
256 vs[i].vs_tty = pccons[i];
257 #endif /* PCVT_NETBSD */
263 pc_tty[totalscreens] = ttymalloc(); /* the mouse emulator tty */
264 #else /* !PCVT_NETBSD */
265 /* the mouse emulator tty */
266 pc_tty[totalscreens] = ttymalloc(pccons[totalscreens]);
267 #endif /* PCVT_NETBSD */
268 #endif /* PCVT_EMU_MOUSE */
272 #else /* !PCVT_NETBSD */
274 #endif /* PCVT_NETBSD */
276 #endif /* #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
278 #else /* !PCVT_NETBSD && !PCVT_FREEBSD*/
295 printf(" <%s,", (char *)vga_string(vga_type));
297 printf("80/132 col");
313 printf(",%d scr,", totalscreens);
315 switch(keyboard_type)
330 printf("kbd,[R%s]>", PCVT_REL);
332 #endif /* PCVT_NETBSD || PCVT_FREEBSD */
334 #if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
335 for(i = 0; i < totalscreens; i++)
337 ttyregister(&pccons[i]);
338 vs[i].vs_tty = &pccons[i];
339 make_dev(&pc_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
341 #endif /* !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
343 async_update(UPDATE_START); /* start asynchronous updates */
347 vthand.ih_fun = pcrint;
349 vthand.ih_level = IPL_TTY;
351 #if (PCVT_NETBSD > 100) && defined(IST_EDGE)
352 intr_establish(ia->ia_irq, IST_EDGE, &vthand);
353 #else /* PCVT_NETBSD > 100 */
354 intr_establish(ia->ia_irq, &vthand);
355 #endif /* PCVT_NETBSD > 100 */
357 #else /* PCVT_NETBSD > 9 */
359 dev->id_ointr = pcrint;
363 #endif /* PCVT_NETBSD > 9 */
367 /* had a look at the friedl driver */
372 get_pccons(Dev_t dev)
374 register int i = minor(dev);
377 if(i == totalscreens)
378 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
382 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
383 #endif /* PCVT_EMU_MOUSE */
385 if(i >= PCVT_NSCREENS)
387 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
397 get_pccons(Dev_t dev)
399 register int i = minor(dev);
402 if(i == totalscreens)
404 #endif /* PCVT_EMU_MOUSE */
406 if(i >= PCVT_NSCREENS)
411 #endif /* !PCVT_NETBSD */
413 /*---------------------------------------------------------------------------*
414 * /dev/ttyc0, /dev/ttyc1, etc.
415 *---------------------------------------------------------------------------*/
417 pcopen(Dev_t dev, int flag, int mode, struct proc *p)
419 register struct tty *tp;
420 register struct video_state *vsx;
426 if(i == totalscreens)
429 #endif /* PCVT_EMU_MOUSE */
433 if((tp = get_pccons(dev)) == NULL)
439 if(i == totalscreens)
441 if(mouse.opened == 0)
442 mouse.buttons = mouse.extendedseen =
443 mouse.breakseen = mouse.lastmove.tv_sec = 0;
448 #endif /* PCVT_EMU_MOUSE */
452 tp->t_oproc = pcstart;
453 tp->t_param = pcparam;
454 tp->t_stop = nottystop;
457 if ((tp->t_state & TS_ISOPEN) == 0)
460 #ifdef TS_WOPEN /* not (FreeBSD-1.1.5 or FreeBSD some time after 2.0.5) */
461 tp->t_state |= TS_WOPEN;
465 tp->t_iflag = TTYDEF_IFLAG;
466 tp->t_oflag = TTYDEF_OFLAG;
467 tp->t_cflag = TTYDEF_CFLAG;
468 tp->t_lflag = TTYDEF_LFLAG;
469 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
470 pcparam(tp, &tp->t_termios);
471 (*linesw[tp->t_line].l_modem)(tp, 1); /* fake connection */
472 winsz = 1; /* set winsize later */
474 else if (tp->t_state & TS_XCLUDE && suser(p))
477 #if PCVT_NETBSD || (PCVT_FREEBSD >= 200)
478 retval = ((*linesw[tp->t_line].l_open)(dev, tp));
480 retval = ((*linesw[tp->t_line].l_open)(dev, tp, flag));
481 #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */
487 * The line discipline has clobbered t_winsize if TS_ISOPEN
488 * was clear. (NetBSD PR #400 from Bill Sommerfeld)
489 * We have to do this after calling the open routine, because
490 * it does some other things in other/older *BSD releases -hm
495 tp->t_winsize.ws_col = vsx->maxcol;
496 tp->t_winsize.ws_row = vsx->screen_rows;
497 tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
498 tp->t_winsize.ws_ypixel = 400;
507 pcclose(Dev_t dev, int flag, int mode, struct proc *p)
509 register struct tty *tp;
510 register struct video_state *vsx;
514 if(i == totalscreens)
517 #endif /* PCVT_EMU_MOUSE */
521 if((tp = get_pccons(dev)) == NULL)
524 (*linesw[tp->t_line].l_close)(tp, flag);
528 if(i == totalscreens)
531 #endif /* PCVT_EMU_MOUSE */
535 #if PCVT_USL_VT_COMPAT
538 if(i == totalscreens)
541 #endif /* PCVT_EMU_MOUSE */
543 reset_usl_modes(vsx);
545 #endif /* PCVT_USL_VT_COMPAT */
551 pcioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
554 register struct tty *tp;
556 if((tp = get_pccons(dev)) == NULL)
559 /* note that some ioctl's are global, e.g. KBSTPMAT: There is
560 * only one keyboard and different repeat rates for instance between
561 * sessions are a suspicious wish. If you really need this make the
562 * appropriate variables arrays
566 if(minor(dev) == totalscreens)
568 if((error = mouse_ioctl(dev, cmd, data)) >= 0)
572 #endif /* PCVT_EMU_MOUSE */
575 #if PCVT_USL_VT_COMPAT
577 if((error = usl_vt_ioctl(dev, cmd, data, flag, p)) >= 0)
581 * just for compatibility:
582 * XFree86 < 2.0 and SuperProbe still might use it
584 * NB: THIS IS A HACK! Do not use it unless you explicitly need.
585 * Especially, since the vty is not put into process-controlled
586 * mode (this would require the application to co-operate), any
587 * attempts to switch vtys while this kind of X mode is active
588 * may cause serious trouble.
592 case CONSOLE_X_MODE_ON:
596 if((error = usl_vt_ioctl(dev, KDENABIO, 0, flag, p)) > 0)
600 if((error = usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, p))
605 error = usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, p);
609 case CONSOLE_X_MODE_OFF:
613 (void)usl_vt_ioctl(dev, KDDISABIO, 0, flag, p);
616 (void)usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, p);
619 (void)usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, p);
627 * If `data' is non-null, the first int value denotes
628 * the pitch, the second a duration. Otherwise, behaves
636 sysbeep(((int *)data)[0],
637 ((int *)data)[1] * hz / 1000);
638 #else /* PCVT_NETBSD */
639 sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
640 ((int *)data)[1] * hz / 3000);
641 #endif /* PCVT_NETBSD */
646 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
650 default: /* fall through */ ;
653 #else /* PCVT_USL_VT_COMPAT */
657 case CONSOLE_X_MODE_ON:
658 return pcvt_xmode_set(1, p);
660 case CONSOLE_X_MODE_OFF:
661 return pcvt_xmode_set(0, p);
666 * If `data' is non-null, the first int value denotes
667 * the pitch, the second a duration. Otherwise, behaves
675 sysbeep(((int *)data)[0],
676 ((int *)data)[1] * hz / 1000);
677 #else /* PCVT_NETBSD */
678 sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
679 ((int *)data)[1] * hz / 3000);
680 #endif /* PCVT_NETBSD */
685 sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
689 default: /* fall through */ ;
692 #endif /* PCVT_USL_VT_COMPAT */
695 if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
698 if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
705 #if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
706 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p))
710 if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag)) >= 0)
712 #endif /* PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 */
715 if((error = ttioctl(tp, cmd, data, flag, p)) >= 0)
718 if((error = ttioctl(tp, cmd, data, flag)) != ENOIOCTL)
720 #endif /* PCVT_NETBSD > 9 */
726 pcmmap(Dev_t dev, vm_offset_t offset, int nprot)
728 if (offset > 0x20000 - PAGE_SIZE)
730 return i386_btop((0xa0000 + offset));
733 /*---------------------------------------------------------------------------*
735 * handle a keyboard receive interrupt
737 * NOTE: the keyboard is multiplexed by means of "pcconsp"
738 * between virtual screens. pcconsp - switching is done in
739 * the vgapage() routine
741 *---------------------------------------------------------------------------*/
745 u_char pcvt_kbd_fifo[PCVT_KBD_FIFO_SZ];
746 static int pcvt_kbd_wptr = 0;
747 int pcvt_kbd_rptr = 0;
748 short pcvt_kbd_count= 0;
749 static u_char pcvt_timeout_scheduled = 0;
752 pcvt_timeout(void *arg)
756 #if PCVT_SLOW_INTERRUPT
760 pcvt_timeout_scheduled = 0;
764 #endif /* PCVT_SCREENSAVER */
766 while (pcvt_kbd_count)
768 if (((cp = sgetc(1)) != 0) &&
769 (vs[current_video_screen].openf))
775 /* pass a NULL character */
776 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
779 #endif /* PCVT_NULLCHARS */
782 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
785 PCVT_DISABLE_INTR ();
788 pcvt_timeout_scheduled = 0;
797 #ifdef _DEV_KBD_KBDREG_H_
799 detect_kbd(void *arg)
806 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
808 kbd = kbd_get_keyboard(i);
811 reset_keyboard = 1; /* ok to reset the keyboard */
816 timeout(detect_kbd, (void *)unit, hz*2);
820 pcevent(keyboard_t *thiskbd, int event, void *arg)
825 return EINVAL; /* shouldn't happen */
831 case KBDIO_UNLOADING:
834 kbd_release(thiskbd, (void *)&kbd);
835 timeout(detect_kbd, (void *)unit, hz*4);
841 #endif /* _DEV_KBD_KBDREG_H_ */
851 # if PCVT_SLOW_INTERRUPT
855 # ifdef _DEV_KBD_KBDREG_H_
859 #else /* !PCVT_KBD_FIFO */
861 #endif /* PCVT_KBD_FIFO */
865 #endif /* PCVT_SCREENSAVER */
874 # ifndef _DEV_KBD_KBDREG_H_
875 while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) /* check 8042 buffer */
877 ret = 1; /* got something */
879 PCVT_KBD_DELAY(); /* 7 us delay */
881 dt = inb(CONTROLLER_DATA); /* get it 8042 data */
883 while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
885 ret = 1; /* got something */
887 # endif /* _DEV_KBD_KBDREG_H_ */
889 if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ) /* fifo overflow ? */
891 log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
895 pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
897 PCVT_DISABLE_INTR (); /* XXX necessary ? */
898 pcvt_kbd_count++; /* update fifo count */
901 if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
902 pcvt_kbd_wptr = 0; /* wraparound pointer */
906 if (ret == 1) /* got data from keyboard ? */
908 if (!pcvt_timeout_scheduled) /* if not already active .. */
910 PCVT_DISABLE_INTR ();
911 pcvt_timeout_scheduled = 1; /* flag active */
912 timeout(pcvt_timeout, NULL, hz / 100); /* fire off */
917 #else /* !PCVT_KBD_FIFO */
919 if((cp = sgetc(1)) == 0)
925 if(!(vs[current_video_screen].openf)) /* XXX was vs[minor(dev)] */
931 /* pass a NULL character */
932 (*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
935 #endif /* PCVT_NULLCHARS */
938 (*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
940 #endif /* PCVT_KBD_FIFO */
944 #if PCVT_NETBSD || PCVT_FREEBSD >= 200
947 pcstart(register struct tty *tp)
949 register struct clist *rbp;
951 u_char buf[PCVT_PCBURST];
955 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
958 tp->t_state |= TS_BUSY;
962 async_update(UPDATE_KERN);
967 * Call q_to_b() at spltty() to ensure that the queue is empty when
968 * the loop terminates.
973 while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
975 if(vs[minor(tp->t_dev)].scrolling)
979 * We need to do this outside spl since it could be fairly
980 * expensive and we don't want our serial ports to overflow.
983 sput(&buf[0], 0, len, minor(tp->t_dev));
987 tp->t_state &= ~TS_BUSY;
989 #ifndef TS_ASLEEP /* FreeBSD some time after 2.0.5 */
992 if (rbp->c_cc <= tp->t_lowat)
994 if (tp->t_state&TS_ASLEEP)
996 tp->t_state &= ~TS_ASLEEP;
997 wakeup((caddr_t)rbp);
999 selwakeup(&tp->t_wsel);
1007 pcstop(struct tty *tp, int flag)
1011 #else /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1014 pcstart(struct tty *tp)
1021 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
1029 #if !(PCVT_FREEBSD > 114)
1031 #if !(PCVT_FREEBSD > 111)
1032 if (RB_LEN(&tp->t_out) <= tp->t_lowat)
1034 if (RB_LEN(tp->t_out) <= tp->t_lowat)
1037 if (tp->t_state&TS_ASLEEP)
1039 tp->t_state &= ~TS_ASLEEP;
1040 #if !(PCVT_FREEBSD > 111)
1041 wakeup((caddr_t)&tp->t_out);
1043 wakeup((caddr_t)tp->t_out);
1049 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
1051 tp->t_state &= ~TS_WCOLL;
1055 #else /* PCVT_FREEBSD > 114 */
1056 if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT)
1060 #endif /* !PCVT_FREEBSD > 114 */
1062 #if !(PCVT_FREEBSD > 111)
1063 if (RB_LEN(&tp->t_out) == 0)
1065 if (RB_LEN(tp->t_out) == 0)
1071 #if !(PCVT_FREEBSD > 111)
1072 c = getc(&tp->t_out);
1074 c = getc(tp->t_out);
1077 tp->t_state |= TS_BUSY; /* patch from Frank Maclachlan */
1079 sput(&c, 0, 1, minor(tp->t_dev));
1081 tp->t_state &= ~TS_BUSY; /* patch from Frank Maclachlan */
1087 #endif /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
1089 /*---------------------------------------------------------------------------*
1091 *---------------------------------------------------------------------------*/
1093 #if !PCVT_NETBSD /* has moved to cons.c in netbsd-current */
1095 consinit() /* init for kernel messages during boot */
1098 #endif /* PCVT_NETBSD */
1100 #if PCVT_FREEBSD > 205
1105 pccnprobe(struct consdev *cp)
1110 /* See if this driver is disabled in probe hint. */
1111 if (resource_int_value("vt", unit, "disabled", &i) == 0 && i) {
1112 cp->cn_pri = CN_DEAD;
1116 #ifdef _DEV_KBD_KBDREG_H_
1117 kbd_configure(KB_CONF_PROBE_ONLY);
1118 if (kbd_find_keyboard("*", unit) < 0)
1120 cp->cn_pri = CN_DEAD;
1123 #endif /* _DEV_KBD_KBDREG_H_ */
1125 /* initialize required fields */
1127 cp->cn_dev = makedev(CDEV_MAJOR, 0);
1128 cp->cn_pri = CN_INTERNAL;
1132 #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
1133 cp->cn_tp = &pccons[0];
1135 cp->cn_tp = pccons[0];
1136 #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
1138 #endif /* !PCVT_NETBSD */
1140 #if PCVT_FREEBSD <= 205
1145 #if PCVT_FREEBSD > 205
1150 pccninit(struct consdev *cp)
1155 pcvt_is_console = 1;
1157 #ifdef _DEV_KBD_KBDREG_H_
1159 * Don't reset the keyboard via `kbdio' just yet.
1160 * The system clock has not been calibrated...
1166 kbd_release(kbd, (void *)&kbd);
1169 i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
1171 kbd = kbd_get_keyboard(i);
1173 #if PCVT_SCANSET == 2
1175 * Turn off scancode translation early so that UserConfig
1176 * and DDB can read the keyboard.
1180 empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
1181 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1182 KBD_TRANSLATION, 0);
1184 #endif /* PCVT_SCANSET == 2 */
1186 #endif /* _DEV_KBD_KBDREG_H_ */
1188 #if PCVT_FREEBSD <= 205
1194 pccnterm(struct consdev *cp)
1196 #ifdef _DEV_KBD_KBDREG_H_
1199 kbd_release(kbd, (void *)&kbd);
1202 #endif /* _DEV_KBD_KBDREG_H_ */
1205 #if PCVT_FREEBSD > 205
1210 pccnputc(Dev_t dev, U_char c)
1215 if(current_video_screen != 0)
1218 #if !PCVT_USL_VT_COMPAT
1221 switch_screen(0, 0);
1222 #endif /* !PCVT_USL_VT_COMPAT */
1226 #endif /* PCVT_SW0CNOUTP */
1229 sput("\r", 1, 1, 0);
1231 sput((char *) &c, 1, 1, 0);
1233 async_update(UPDATE_KERN);
1235 #if PCVT_FREEBSD <= 205
1244 static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
1249 #if !PCVT_USL_VT_COMPAT
1252 #else /* !PCVT_USL_VT_COMPAT */
1255 #endif /* !PCVT_USL_VT_COMPAT */
1257 #endif /* XSERVER */
1261 * We still have a pending key sequence, e.g.
1262 * from an arrow key. Deliver this one first.
1266 #ifdef _DEV_KBD_KBDREG_H_
1271 s = spltty(); /* block pcrint while we poll */
1273 #ifdef _DEV_KBD_KBDREG_H_
1274 (*kbdsw[kbd->kb_index]->enable)(kbd);
1277 #ifdef _DEV_KBD_KBDREG_H_
1278 (*kbdsw[kbd->kb_index]->disable)(kbd);
1284 /* Preserve the multi-char sequence for the next call. */
1285 bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
1290 #if ! (PCVT_FREEBSD >= 201)
1291 /* this belongs to cons.c */
1294 #endif /* ! (PCVT_FREEBSD >= 201) */
1299 #if PCVT_FREEBSD >= 200
1301 pccncheckc(Dev_t dev)
1306 #ifdef _DEV_KBD_KBDREG_H_
1313 #ifdef _DEV_KBD_KBDREG_H_
1314 (*kbdsw[kbd->kb_index]->enable)(kbd);
1317 #ifdef _DEV_KBD_KBDREG_H_
1318 (*kbdsw[kbd->kb_index]->disable)(kbd);
1322 return (cp == NULL ? -1 : *cp);
1324 #endif /* PCVT_FREEBSD >= 200 */
1326 #if PCVT_NETBSD >= 100
1328 pccnpollc(Dev_t dev, int on)
1335 * If disabling polling, make sure there are no bytes left in
1336 * the FIFO, holding up the interrupt line. Otherwise we
1337 * won't get any further interrupts.
1344 #endif /* PCVT_NETBSD >= 100 */
1346 /*---------------------------------------------------------------------------*
1347 * Set line parameters
1348 *---------------------------------------------------------------------------*/
1350 pcparam(struct tty *tp, struct termios *t)
1352 register int cflag = t->c_cflag;
1354 /* and copy to tty */
1356 tp->t_ispeed = t->c_ispeed;
1357 tp->t_ospeed = t->c_ospeed;
1358 tp->t_cflag = cflag;
1363 /*----------------------------------------------------------------------*
1364 * read initial VGA palette (as stored by VGA ROM BIOS) into
1366 *----------------------------------------------------------------------*/
1370 register unsigned idx;
1371 register struct rgb *val;
1373 /* first, read all and store to first screen's save buffer */
1374 for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
1375 vgapaletteio(idx, val, 0 /* read it */);
1377 /* now, duplicate for remaining screens */
1378 for(idx = 1; idx < PCVT_NSCREENS; idx++)
1379 bcopy(vs[0].palette, vs[idx].palette,
1380 NVGAPEL * sizeof(struct rgb));
1383 #if defined XSERVER && !PCVT_USL_VT_COMPAT
1384 /*----------------------------------------------------------------------*
1385 * initialize for X mode
1386 * i.e.: grant current process (the X server) all IO privileges,
1387 * and mark in static variable so other hooks can test for it,
1388 * save all loaded fonts and screen pages to pageable buffers;
1389 * if parameter `on' is false, the same procedure is done reverse.
1390 *----------------------------------------------------------------------*/
1392 pcvt_xmode_set(int on, struct proc *p)
1394 static unsigned char *saved_fonts[NVGAFONTS];
1396 #if PCVT_SCREENSAVER
1397 static unsigned saved_scrnsv_tmo = 0;
1398 #endif /* PCVT_SCREENSAVER */
1400 #if (PCVT_NETBSD > 9) || (PCVT_FREEBSD > 102)
1401 struct trapframe *fp;
1403 struct syscframe *fp;
1404 #endif /* PCVT_NETBSD > 9 */
1408 /* X will only run on VGA and Hercules adaptors */
1410 if(adaptor_type != VGA_ADAPTOR && adaptor_type != MDA_ADAPTOR)
1414 fp = (struct trapframe *)p->p_regs;
1416 fp = (struct syscframe *)p->p_regs;
1417 #endif /* PCVT_NETBSD > 9 */
1422 * Test whether the calling process has super-user privileges
1423 * and we're in insecure mode.
1424 * This prevents us from granting the potential security hole
1425 * `IO priv' to insufficiently privileged processes.
1430 if (securelevel > 0)
1436 pcvt_xmode = pcvt_kbd_raw = 1;
1438 for(i = 0; i < totalfonts; i++)
1442 saved_fonts[i] = (unsigned char *)
1443 malloc(32 * 256, M_DEVBUF, M_WAITOK);
1444 if(saved_fonts[i] == 0)
1447 "pcvt_xmode_set: no font buffer available\n");
1452 vga_move_charset(i, saved_fonts[i], 1);
1461 #if PCVT_SCREENSAVER
1462 if(saved_scrnsv_tmo = scrnsv_timeout)
1463 pcvt_set_scrnsv_tmo(0); /* turn it off */
1464 #endif /* PCVT_SCREENSAVER */
1466 async_update(UPDATE_STOP); /* turn off */
1468 /* disable text output and save screen contents */
1469 /* video board memory -> kernel memory */
1471 bcopy(vsp->Crtat, vsp->Memory,
1472 vsp->screen_rowsize * vsp->maxcol * CHR);
1474 vsp->Crtat = vsp->Memory; /* operate in memory now */
1476 #ifndef _DEV_KBD_KBDREG_H_
1478 #if PCVT_SCANSET == 2
1479 /* put keyboard to return ancient PC scan codes */
1480 kbc_8042cmd(CONTR_WRITE);
1481 #if PCVT_USEKBDSEC /* security enabled */
1482 outb(CONTROLLER_DATA,
1483 (COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1484 #else /* security disabled */
1485 outb(CONTROLLER_DATA,
1486 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
1487 #endif /* PCVT_USEKBDSEC */
1488 #endif /* PCVT_SCANSET == 2 */
1490 #else /* _DEV_KBD_KBDREG_H_ */
1492 #if PCVT_SCANSET == 2
1493 /* put keyboard to return ancient PC scan codes */
1494 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1495 KBD_TRANSLATION, KBD_TRANSLATION);
1496 #endif /* PCVT_SCANSET == 2 */
1498 #endif /* !_DEV_KBD_KBDREG_H_ */
1501 fp->tf_eflags |= PSL_IOPL;
1503 fp->sf_eflags |= PSL_IOPL;
1504 #endif /* PCVT_NETBSD > 9 */
1509 if(!pcvt_xmode) /* verify if in X */
1512 pcvt_xmode = pcvt_kbd_raw = 0;
1514 for(i = 0; i < totalfonts; i++)
1518 vga_move_charset(i, saved_fonts[i], 0);
1519 free(saved_fonts[i], M_DEVBUF);
1525 fp->tf_eflags &= ~PSL_IOPL;
1527 fp->sf_eflags &= ~PSL_IOPL;
1528 #endif /* PCVT_NETBSD > 9 */
1530 #if PCVT_SCREENSAVER
1531 if(saved_scrnsv_tmo)
1532 pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);
1533 #endif /* PCVT_SCREENSAVER */
1535 #ifndef _DEV_KBD_KBDREG_H_
1537 #if PCVT_SCANSET == 2
1538 kbc_8042cmd(CONTR_WRITE);
1539 #if PCVT_USEKBDSEC /* security enabled */
1540 outb(CONTROLLER_DATA,
1541 (COMMAND_SYSFLG|COMMAND_IRQEN));
1542 #else /* security disabled */
1543 outb(CONTROLLER_DATA,
1544 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN));
1545 #endif /* PCVT_USEKBDSEC */
1546 #endif /* PCVT_SCANSET == 2 */
1548 #else /* _DEV_KBD_KBDREG_H_ */
1550 #if PCVT_SCANSET == 2
1551 set_controller_command_byte(*(KBDC *)kbd->kb_data,
1552 KBD_TRANSLATION, 0);
1553 #endif /* PCVT_SCANSET == 2 */
1555 #endif /* !_DEV_KBD_KBDREG_H_ */
1557 if(adaptor_type == MDA_ADAPTOR)
1560 * Due to the fact that HGC registers are write-only,
1561 * the Xserver can only make guesses about the state
1562 * the HGC adaptor has been before turning on X mode.
1563 * Thus, the display must be re-enabled now, and the
1564 * cursor shape and location restored.
1566 outb(GN_DMCNTLM, 0x28); /* enable display, text mode */
1567 outb(addr_6845, CRTC_CURSORH); /* select high register */
1569 ((vsp->Crtat + vsp->cur_offset) - Crtat) >> 8);
1570 outb(addr_6845, CRTC_CURSORL); /* select low register */
1572 ((vsp->Crtat + vsp->cur_offset) - Crtat));
1574 outb(addr_6845, CRTC_CURSTART); /* select high register */
1575 outb(addr_6845+1, vsp->cursor_start);
1576 outb(addr_6845, CRTC_CUREND); /* select low register */
1577 outb(addr_6845+1, vsp->cursor_end);
1580 /* restore screen and re-enable text output */
1581 /* kernel memory -> video board memory */
1583 bcopy(vsp->Memory, Crtat,
1584 vsp->screen_rowsize * vsp->maxcol * CHR);
1586 vsp->Crtat = Crtat; /* operate on-screen now */
1588 /* set crtc screen memory start address */
1590 outb(addr_6845, CRTC_STARTADRH);
1591 outb(addr_6845+1, (vsp->Crtat - Crtat) >> 8);
1592 outb(addr_6845, CRTC_STARTADRL);
1593 outb(addr_6845+1, (vsp->Crtat - Crtat));
1595 async_update(UPDATE_START);
1599 #endif /* XSERVER && !PCVT_USL_VT_COMPAT */
1601 #endif /* NVT > 0 */
1603 /*-------------------------- E O F -------------------------------------*/