File:  [DragonFly] / src / sys / dev / video / pcvt / i386 / Attic / pcvt_drv.c
Revision 1.9: download - view: text, annotated - select for diffs
Thu May 13 23:49:23 2004 UTC (10 years, 5 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
device switch 1/many: Remove d_autoq, add d_clone (where d_autoq was).

d_autoq was used to allow the device port dispatch to mix old-style synchronous
calls with new style messaging calls within a particular device.  It was never
used for that purpose.

d_clone will be more fully implemented as work continues.  We are going to
install d_port in the dev_t (struct specinfo) structure itself and d_clone
will be needed to allow devices to 'revector' the port on a minor-number
by minor-number basis, in particular allowing minor numbers to be directly
dispatched to distinct threads.  This is something we will be needing later
on.

    1: /*
    2:  * Copyright (c) 1999 Hellmuth Michaelis
    3:  *
    4:  * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
    5:  *
    6:  * Copyright (c) 1992, 1993 Brian Dunford-Shore and Scott Turner.
    7:  *
    8:  * Copyright (c) 1993 Charles Hannum.
    9:  *
   10:  * All rights reserved.
   11:  *
   12:  * Parts of this code regarding the NetBSD interface were written
   13:  * by Charles Hannum.
   14:  *
   15:  * This code is derived from software contributed to Berkeley by
   16:  * William Jolitz and Don Ahn.
   17:  *
   18:  * Redistribution and use in source and binary forms, with or without
   19:  * modification, are permitted provided that the following conditions
   20:  * are met:
   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
   30:  *	and Charles Hannum.
   31:  * 4. The name authors may not be used to endorse or promote products
   32:  *    derived from this software without specific prior written permission.
   33:  *
   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.
   44:  */
   45: 
   46: /*---------------------------------------------------------------------------*
   47:  *
   48:  *	pcvt_drv.c	VT220 Driver Main Module / OS - Interface
   49:  *	---------------------------------------------------------
   50:  *
   51:  *	Last Edit-Date: [Mon Dec 27 14:03:36 1999]
   52:  *
   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/pcvt_drv.c,v 1.9 2004/05/13 23:49:23 dillon Exp $
   55:  *
   56:  *---------------------------------------------------------------------------*/
   57: 
   58: #include "use_vt.h"
   59: #if NVT > 0
   60: 
   61: #define EXTERN			/* allocate mem */
   62: 
   63: #include "pcvt_hdr.h"	/* global include */
   64: 
   65: #if PCVT_FREEBSD >= 200
   66: #include <sys/bus.h>
   67: #include <machine/stdarg.h>
   68: #else
   69: #include "machine/stdarg.h"
   70: #endif
   71: 
   72: extern int getchar (void);
   73: 
   74: #if PCVT_NETBSD
   75: 	extern u_short *Crtat;
   76: #endif /* PCVT_NETBSD */
   77: 
   78: static void vgapelinit(void);	/* read initial VGA DAC palette */
   79: 
   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 */
   83: 
   84: #ifdef _DEV_KBD_KBDREG_H_
   85: static void detect_kbd(void *arg);
   86: static kbd_callback_func_t pcevent;
   87: #endif
   88: 
   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;
   95: 
   96: CONS_DRIVER(pc, pccnprobe, pccninit, pccnterm, pccngetc, pccncheckc, pccnputc,
   97: 	    NULL);
   98: 
   99: static	d_open_t	pcopen;
  100: static	d_close_t	pcclose;
  101: static	d_ioctl_t	pcioctl;
  102: static	d_mmap_t	pcmmap;
  103: 
  104: #define	CDEV_MAJOR	12
  105: static struct cdevsw pc_cdevsw = {
  106: 	/* name */	"vt",
  107: 	/* maj */	CDEV_MAJOR,
  108: 	/* flags */	D_TTY | D_KQFILTER,
  109: 	/* port */	NULL,
  110: 	/* clone */	NULL,
  111: 
  112: 	/* open */	pcopen,
  113: 	/* close */	pcclose,
  114: 	/* read */	ttyread,
  115: 	/* write */	ttywrite,
  116: 	/* ioctl */	pcioctl,
  117: 	/* poll */	ttypoll,
  118: 	/* mmap */	pcmmap,
  119: 	/* strategy */	nostrategy,
  120: 	/* dump */	nodump,
  121: 	/* psize */	nopsize,
  122: 	/* kqfilter */	ttykqfilter
  123: };
  124: 
  125: #if PCVT_NETBSD > 100	/* NetBSD-current Feb 20 1995 */
  126: int
  127: pcprobe(struct device *parent, void *match, void *aux)
  128: #else
  129: #if PCVT_NETBSD > 9
  130: int
  131: pcprobe(struct device *parent, struct device *self, void *aux)
  132: #else
  133: int
  134: pcprobe(struct isa_device *dev)
  135: #endif /* PCVT_NETBSD > 9 */
  136: #endif /* PCVT_NETBSD > 100 */
  137: {
  138: #ifdef _DEV_KBD_KBDREG_H_
  139: 	int i;
  140: 
  141: 	if (kbd == NULL) {
  142: 		reset_keyboard = 0;
  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))
  146: 			return (-1);
  147: 	}
  148: 	reset_keyboard = 1;		/* it's now safe to do kbd reset */
  149: #endif /* _DEV_KBD_KBDREG_H_ */
  150: 
  151: 	kbd_code_init();
  152: 
  153: #if PCVT_NETBSD > 9
  154: 	((struct isa_attach_args *)aux)->ia_iosize = 16;
  155: 	return 1;
  156: #else
  157: #ifdef _DEV_KBD_KBDREG_H_
  158: 	return (-1);
  159: #elif PCVT_NETBSD || PCVT_FREEBSD
  160: 	return (16);
  161: #else
  162: 	return 1;
  163: #endif /* PCVT_NETBSD || PCVT_FREEBSD */
  164: #endif /* PCVT_NETBSD > 9 */
  165: 
  166: }
  167: 
  168: #if PCVT_NETBSD > 9
  169: void
  170: pcattach(struct device *parent, struct device *self, void *aux)
  171: {
  172: 	struct isa_attach_args *ia = aux;
  173: 	static struct intrhand vthand;
  174: #else
  175: int
  176: pcattach(struct isa_device *dev)
  177: {
  178: #endif /* PCVT_NETBSD > 9 */
  179: 
  180: 	int i;
  181: 
  182: 	vt_coldmalloc();		/* allocate memory for screens */
  183: 
  184: #ifdef _DEV_KBD_KBDREG_H_
  185: 	if (kbd == NULL)
  186: 		timeout(detect_kbd, (void *)dev->id_unit, hz*2);
  187: #endif /* _DEV_KBD_KBDREG_H_ */
  188: 
  189: #if PCVT_NETBSD || PCVT_FREEBSD
  190: 
  191: #if PCVT_NETBSD > 9
  192: 	printf(": ");
  193: #else
  194: 	printf("vt%d: ", dev->id_unit);
  195: #endif /* PCVT_NETBSD > 9 */
  196: 
  197: 	switch(adaptor_type)
  198: 	{
  199: 		case MDA_ADAPTOR:
  200: 			printf("mda");
  201: 			break;
  202: 
  203: 		case CGA_ADAPTOR:
  204: 			printf("cga");
  205: 			break;
  206: 
  207: 		case EGA_ADAPTOR:
  208: 			printf("ega");
  209: 			break;
  210: 
  211: 		case VGA_ADAPTOR:
  212: 			printf("%s, ", (char *)vga_string(vga_type));
  213: 			if(can_do_132col)
  214: 				printf("80/132 col");
  215: 			else
  216: 				printf("80 col");
  217: 			vgapelinit();
  218: 			break;
  219: 
  220: 		default:
  221: 			printf("unknown");
  222: 			break;
  223: 	}
  224: 
  225: 	if(color == 0)
  226: 		printf(", mono");
  227: 	else
  228: 		printf(", color");
  229: 
  230: 	printf(", %d scr, ", totalscreens);
  231: 
  232: 	switch(keyboard_type)
  233: 	{
  234: 		case KB_AT:
  235: 			printf("at-");
  236: 			break;
  237: 
  238: 		case KB_MFII:
  239: 			printf("mf2-");
  240: 			break;
  241: 
  242: 		default:
  243: 			printf("unknown ");
  244: 			break;
  245: 	}
  246: 
  247: 	printf("kbd, [R%s]\n", PCVT_REL);
  248: 
  249: #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
  250: 
  251: 	for(i = 0; i < totalscreens; i++)
  252: 	{
  253: 
  254: #if PCVT_NETBSD
  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 */
  261: 
  262: 	}
  263: 
  264: #if PCVT_EMU_MOUSE
  265: #if 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 */
  272: 
  273: #if PCVT_NETBSD
  274: 	pcconsp = pc_tty[0];
  275: #else  /* !PCVT_NETBSD */
  276: 	pcconsp = pccons[0];
  277: #endif  /* PCVT_NETBSD */
  278: 
  279: #endif /* #if PCVT_NETBSD || (PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
  280: 
  281: #else /* !PCVT_NETBSD && !PCVT_FREEBSD*/
  282: 
  283: 	switch(adaptor_type)
  284: 	{
  285: 		case MDA_ADAPTOR:
  286: 			printf(" <mda");
  287: 			break;
  288: 
  289: 		case CGA_ADAPTOR:
  290: 			printf(" <cga");
  291: 			break;
  292: 
  293: 		case EGA_ADAPTOR:
  294: 			printf(" <ega");
  295: 			break;
  296: 
  297: 		case VGA_ADAPTOR:
  298: 			printf(" <%s,", (char *)vga_string(vga_type));
  299: 			if(can_do_132col)
  300: 				printf("80/132 col");
  301: 			else
  302: 				printf("80 col");
  303: 			vgapelinit();
  304: 			break;
  305: 
  306: 		default:
  307: 			printf(" <unknown");
  308: 			break;
  309: 	}
  310: 
  311: 	if(color == 0)
  312: 		printf(",mono");
  313: 	else
  314: 		printf(",color");
  315: 
  316: 	printf(",%d scr,", totalscreens);
  317: 
  318: 	switch(keyboard_type)
  319: 	{
  320: 		case KB_AT:
  321: 			printf("at-");
  322: 			break;
  323: 
  324: 		case KB_MFII:
  325: 			printf("mf2-");
  326: 			break;
  327: 
  328: 		default:
  329: 			printf("unknown ");
  330: 			break;
  331: 	}
  332: 
  333: 	printf("kbd,[R%s]>", PCVT_REL);
  334: 
  335: #endif  /* PCVT_NETBSD || PCVT_FREEBSD */
  336: 
  337: #if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
  338: 	for(i = 0; i < totalscreens; i++)
  339: 	{
  340: 		ttyregister(&pccons[i]);
  341: 		vs[i].vs_tty = &pccons[i];
  342: 		make_dev(&pc_cdevsw, i, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", i);
  343: 	}
  344: #endif /* !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
  345: 
  346: 	async_update(UPDATE_START);	/* start asynchronous updates */
  347: 
  348: #if PCVT_NETBSD > 9
  349: 
  350: 	vthand.ih_fun = pcrint;
  351: 	vthand.ih_arg = 0;
  352: 	vthand.ih_level = IPL_TTY;
  353: 
  354: #if (PCVT_NETBSD > 100) && defined(IST_EDGE)
  355: 	intr_establish(ia->ia_irq, IST_EDGE, &vthand);
  356: #else /* PCVT_NETBSD > 100 */
  357: 	intr_establish(ia->ia_irq, &vthand);
  358: #endif /* PCVT_NETBSD > 100 */
  359: 
  360: #else /* PCVT_NETBSD > 9 */
  361: 
  362: 	dev->id_ointr = pcrint;
  363: 
  364: 	return 1;
  365: 
  366: #endif /* PCVT_NETBSD > 9 */
  367: 
  368: }
  369: 
  370: /* had a look at the friedl driver */
  371: 
  372: #if !PCVT_NETBSD
  373: 
  374: struct tty *
  375: get_pccons(Dev_t dev)
  376: {
  377: 	int i = minor(dev);
  378: 
  379: #if PCVT_EMU_MOUSE
  380:  	if(i == totalscreens)
  381: #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
  382:  		return(&pccons[i]);
  383: #else
  384:  		return(pccons[i]);
  385: #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
  386: #endif /* PCVT_EMU_MOUSE */
  387: 
  388: 	if(i >= PCVT_NSCREENS)
  389: 		return(NULL);
  390: #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
  391: 	return(&pccons[i]);
  392: #else
  393: 	return(pccons[i]);
  394: #endif
  395: }
  396: 
  397: #else
  398: 
  399: struct tty *
  400: get_pccons(Dev_t dev)
  401: {
  402: 	int i = minor(dev);
  403: 
  404: #if PCVT_EMU_MOUSE
  405: 	if(i == totalscreens)
  406: 		return(pc_tty[i]);
  407: #endif /* PCVT_EMU_MOUSE */
  408: 
  409: 	if(i >= PCVT_NSCREENS)
  410: 		return(NULL);
  411: 	return(pc_tty[i]);
  412: }
  413: 
  414: #endif /* !PCVT_NETBSD */
  415: 
  416: /*---------------------------------------------------------------------------*
  417:  *		/dev/ttyc0, /dev/ttyc1, etc.
  418:  *---------------------------------------------------------------------------*/
  419: int
  420: pcopen(Dev_t dev, int flag, int mode, struct thread *td)
  421: {
  422: 	struct tty *tp;
  423: 	struct video_state *vsx;
  424: 	int s, retval;
  425: 	int winsz = 0;
  426: 	int i = minor(dev);
  427: 
  428: #if PCVT_EMU_MOUSE
  429: 	if(i == totalscreens)
  430: 		vsx = 0;
  431: 	else
  432: #endif /* PCVT_EMU_MOUSE */
  433: 
  434: 	vsx = &vs[i];
  435: 
  436:   	if((tp = get_pccons(dev)) == NULL)
  437: 		return ENXIO;
  438: 
  439: 	dev->si_tty = tp;
  440: 
  441: #if PCVT_EMU_MOUSE
  442: 	if(i == totalscreens)
  443: 	{
  444: 		if(mouse.opened == 0)
  445: 			mouse.buttons = mouse.extendedseen =
  446: 				mouse.breakseen = mouse.lastmove.tv_sec = 0;
  447: 		mouse.minor = i;
  448: 		mouse.opened++;
  449: 	}
  450: 	else
  451: #endif /* PCVT_EMU_MOUSE */
  452: 
  453: 	vsx->openf++;
  454: 
  455: 	tp->t_oproc = pcstart;
  456: 	tp->t_param = pcparam;
  457: 	tp->t_stop = nottystop;
  458: 	tp->t_dev = dev;
  459: 
  460: 	if ((tp->t_state & TS_ISOPEN) == 0)
  461: 	{
  462: 
  463: #ifdef TS_WOPEN /* not (FreeBSD-1.1.5 or FreeBSD some time after 2.0.5) */
  464: 		tp->t_state |= TS_WOPEN;
  465: #endif
  466: 
  467: 		ttychars(tp);
  468: 		tp->t_iflag = TTYDEF_IFLAG;
  469: 		tp->t_oflag = TTYDEF_OFLAG;
  470: 		tp->t_cflag = TTYDEF_CFLAG;
  471: 		tp->t_lflag = TTYDEF_LFLAG;
  472: 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
  473: 		pcparam(tp, &tp->t_termios);
  474: 		(*linesw[tp->t_line].l_modem)(tp, 1);	/* fake connection */
  475: 		winsz = 1;			/* set winsize later */
  476: 	}
  477: 	else if (tp->t_state & TS_XCLUDE && suser(td))
  478: 		return (EBUSY);
  479: 
  480: #if PCVT_NETBSD || (PCVT_FREEBSD >= 200)
  481: 	retval = ((*linesw[tp->t_line].l_open)(dev, tp));
  482: #else
  483: 	retval = ((*linesw[tp->t_line].l_open)(dev, tp, flag));
  484: #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */
  485: 
  486: 	if(winsz == 1)
  487: 	{
  488: 
  489: 		/*
  490: 		 * The line discipline has clobbered t_winsize if TS_ISOPEN
  491: 	         * was clear. (NetBSD PR #400 from Bill Sommerfeld)
  492: 	         * We have to do this after calling the open routine, because
  493: 	         * it does some other things in other/older *BSD releases -hm
  494: 		 */
  495: 
  496: 		s = spltty();
  497: 
  498: 		tp->t_winsize.ws_col = vsx->maxcol;
  499: 		tp->t_winsize.ws_row = vsx->screen_rows;
  500: 		tp->t_winsize.ws_xpixel = (vsx->maxcol == 80)? 720: 1056;
  501: 		tp->t_winsize.ws_ypixel = 400;
  502: 
  503: 		splx(s);
  504: 	}
  505: 
  506: 	return(retval);
  507: }
  508: 
  509: int
  510: pcclose(Dev_t dev, int flag, int mode, struct thread *td)
  511: {
  512: 	struct tty *tp;
  513: 	struct video_state *vsx;
  514: 	int i = minor(dev);
  515: 
  516: #if PCVT_EMU_MOUSE
  517: 	if(i == totalscreens)
  518: 		vsx = 0;
  519: 	else
  520: #endif /* PCVT_EMU_MOUSE */
  521: 
  522: 	vsx = &vs[i];
  523: 
  524: 	if((tp = get_pccons(dev)) == NULL)
  525: 		return ENXIO;
  526: 
  527: 	(*linesw[tp->t_line].l_close)(tp, flag);
  528: 	ttyclose(tp);
  529: 
  530: #if PCVT_EMU_MOUSE
  531: 	if(i == totalscreens)
  532: 		mouse.opened = 0;
  533: 	else
  534: #endif /* PCVT_EMU_MOUSE */
  535: 
  536: 	vsx->openf = 0;
  537: 
  538: #if PCVT_USL_VT_COMPAT
  539: #if PCVT_EMU_MOUSE
  540: 
  541: 	if(i == totalscreens)
  542: 		return (0);
  543: 
  544: #endif /* PCVT_EMU_MOUSE */
  545: 
  546: 	reset_usl_modes(vsx);
  547: 
  548: #endif /* PCVT_USL_VT_COMPAT */
  549: 
  550: 	return(0);
  551: }
  552: 
  553: int
  554: pcioctl(Dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
  555: {
  556: 	int error;
  557: 	struct tty *tp;
  558: 
  559: 	if((tp = get_pccons(dev)) == NULL)
  560: 		return(ENXIO);
  561: 
  562: 	/* note that some ioctl's are global, e.g.  KBSTPMAT: There is
  563: 	 * only one keyboard and different repeat rates for instance between
  564: 	 * sessions are a suspicious wish. If you really need this make the
  565: 	 * appropriate variables arrays
  566: 	 */
  567: 
  568: #if PCVT_EMU_MOUSE
  569: 	if(minor(dev) == totalscreens)
  570: 	{
  571: 		if((error = mouse_ioctl(dev, cmd, data)) >= 0)
  572: 			return error;
  573: 		goto do_standard;
  574: 	}
  575: #endif /* PCVT_EMU_MOUSE */
  576: 
  577: #ifdef XSERVER
  578: #if PCVT_USL_VT_COMPAT
  579: 
  580: 	if((error = usl_vt_ioctl(dev, cmd, data, flag, td->td_proc)) >= 0)
  581: 		return error;
  582: 
  583: 	/*
  584: 	 * just for compatibility:
  585: 	 * XFree86 < 2.0 and SuperProbe still might use it
  586: 	 *
  587: 	 * NB: THIS IS A HACK! Do not use it unless you explicitly need.
  588: 	 * Especially, since the vty is not put into process-controlled
  589: 	 * mode (this would require the application to co-operate), any
  590: 	 * attempts to switch vtys while this kind of X mode is active
  591: 	 * may cause serious trouble.
  592: 	 */
  593: 	switch(cmd)
  594: 	{
  595: 	  case CONSOLE_X_MODE_ON:
  596: 	  {
  597: 	    int i;
  598: 
  599: 	    if((error = usl_vt_ioctl(dev, KDENABIO, 0, flag, td->td_proc)) > 0)
  600: 	      return error;
  601: 
  602: 	    i = KD_GRAPHICS;
  603: 	    if((error = usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, td->td_proc))
  604: 	       > 0)
  605: 	      return error;
  606: 
  607: 	    i = K_RAW;
  608: 	    error = usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, td->td_proc);
  609: 	    return error;
  610: 	  }
  611: 
  612: 	  case CONSOLE_X_MODE_OFF:
  613: 	  {
  614: 	    int i;
  615: 
  616: 	    (void)usl_vt_ioctl(dev, KDDISABIO, 0, flag, td->td_proc);
  617: 
  618: 	    i = KD_TEXT;
  619: 	    (void)usl_vt_ioctl(dev, KDSETMODE, (caddr_t)&i, flag, td->td_proc);
  620: 
  621: 	    i = K_XLATE;
  622: 	    (void)usl_vt_ioctl(dev, KDSKBMODE, (caddr_t)&i, flag, td->td_proc);
  623: 	    return 0;
  624: 	  }
  625: 
  626: 
  627: 	  case CONSOLE_X_BELL:
  628: 
  629: 		/*
  630: 		 * If `data' is non-null, the first int value denotes
  631: 		 * the pitch, the second a duration. Otherwise, behaves
  632: 		 * like BEL.
  633: 		 */
  634: 
  635: 		if (data)
  636: 		{
  637: 
  638: #if PCVT_NETBSD
  639: 			sysbeep(((int *)data)[0],
  640: 				((int *)data)[1] * hz / 1000);
  641: #else /* PCVT_NETBSD */
  642: 			sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
  643: 				((int *)data)[1] * hz / 3000);
  644: #endif /* PCVT_NETBSD */
  645: 
  646: 		}
  647: 		else
  648: 		{
  649: 			sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
  650: 		}
  651: 		return (0);
  652: 
  653: 	  default: /* fall through */ ;
  654: 	}
  655: 
  656: #else /* PCVT_USL_VT_COMPAT */
  657: 
  658: 	switch(cmd)
  659: 	{
  660: 	  case CONSOLE_X_MODE_ON:
  661: 		return pcvt_xmode_set(1, td->td_proc);
  662: 
  663: 	  case CONSOLE_X_MODE_OFF:
  664: 		return pcvt_xmode_set(0, td->td_proc);
  665: 
  666: 	  case CONSOLE_X_BELL:
  667: 
  668: 		/*
  669: 		 * If `data' is non-null, the first int value denotes
  670: 		 * the pitch, the second a duration. Otherwise, behaves
  671: 		 * like BEL.
  672: 		 */
  673: 
  674: 		if (data)
  675: 		{
  676: 
  677: #if PCVT_NETBSD
  678: 			sysbeep(((int *)data)[0],
  679: 				((int *)data)[1] * hz / 1000);
  680: #else /* PCVT_NETBSD */
  681: 			sysbeep(PCVT_SYSBEEPF / ((int *)data)[0],
  682: 				((int *)data)[1] * hz / 3000);
  683: #endif /* PCVT_NETBSD */
  684: 
  685: 		}
  686: 		else
  687: 		{
  688: 			sysbeep(PCVT_SYSBEEPF / 1493, hz / 4);
  689: 		}
  690: 		return (0);
  691: 
  692: 	  default: /* fall through */ ;
  693: 	}
  694: 
  695: #endif /* PCVT_USL_VT_COMPAT */
  696: #endif /* XSERVER */
  697: 
  698: 	if((error = kbdioctl(dev,cmd,data,flag)) >= 0)
  699: 		return error;
  700: 
  701: 	if((error = vgaioctl(dev,cmd,data,flag)) >= 0)
  702: 		return error;
  703: 
  704: #if PCVT_EMU_MOUSE
  705: do_standard:
  706: #endif
  707: 
  708: #if PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200
  709: 	if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td))
  710: 	    != ENOIOCTL)
  711: 		return (error);
  712: #else
  713: 	if((error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag)) >= 0)
  714: 		return(error);
  715: #endif /* PCVT_NETBSD > 9 || PCVT_FREEBSD >= 200 */
  716: 
  717: #if PCVT_NETBSD > 9
  718: 	if((error = ttioctl(tp, cmd, data, flag, td)) >= 0)
  719: 		return (error);
  720: #else
  721: 	if((error = ttioctl(tp, cmd, data, flag)) != ENOIOCTL)
  722: 		return (error);
  723: #endif /* PCVT_NETBSD > 9 */
  724: 
  725: 	return (ENOTTY);
  726: }
  727: 
  728: int
  729: pcmmap(Dev_t dev, vm_offset_t offset, int nprot)
  730: {
  731: 	if (offset > 0x20000 - PAGE_SIZE)
  732: 		return -1;
  733: 	return i386_btop((0xa0000 + offset));
  734: }
  735: 
  736: /*---------------------------------------------------------------------------*
  737:  *
  738:  *	handle a keyboard receive interrupt
  739:  *
  740:  *	NOTE: the keyboard is multiplexed by means of "pcconsp"
  741:  *	between virtual screens. pcconsp - switching is done in
  742:  *	the vgapage() routine
  743:  *
  744:  *---------------------------------------------------------------------------*/
  745: 
  746: #if PCVT_KBD_FIFO
  747: 
  748: u_char pcvt_kbd_fifo[PCVT_KBD_FIFO_SZ];
  749: static int pcvt_kbd_wptr = 0;
  750: int pcvt_kbd_rptr = 0;
  751: short pcvt_kbd_count= 0;
  752: static u_char pcvt_timeout_scheduled = 0;
  753: 
  754: static void
  755: pcvt_timeout(void *arg)
  756: {
  757: 	u_char *cp;
  758: 
  759: #if PCVT_SLOW_INTERRUPT
  760: 	int	s;
  761: #endif
  762: 
  763: 	pcvt_timeout_scheduled = 0;
  764: 
  765: #if PCVT_SCREENSAVER
  766: 	pcvt_scrnsv_reset();
  767: #endif /* PCVT_SCREENSAVER */
  768: 
  769: 	while (pcvt_kbd_count)
  770: 	{
  771: 		if (((cp = sgetc(1)) != 0) &&
  772: 		    (vs[current_video_screen].openf))
  773: 		{
  774: 
  775: #if PCVT_NULLCHARS
  776: 			if(*cp == '\0')
  777: 			{
  778: 				/* pass a NULL character */
  779: 				(*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
  780: 			}
  781: /* XXX */		else
  782: #endif /* PCVT_NULLCHARS */
  783: 
  784: 			while (*cp)
  785: 				(*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
  786: 		}
  787: 
  788: 		PCVT_DISABLE_INTR ();
  789: 
  790: 		if (!pcvt_kbd_count)
  791: 			pcvt_timeout_scheduled = 0;
  792: 
  793: 		PCVT_ENABLE_INTR ();
  794: 	}
  795: 
  796: 	return;
  797: }
  798: #endif
  799: 
  800: #ifdef _DEV_KBD_KBDREG_H_
  801: static void
  802: detect_kbd(void *arg)
  803: {
  804: 	int unit = (int)arg;
  805: 	int i;
  806: 
  807: 	if (kbd != NULL)
  808: 		return;
  809: 	i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
  810: 	if (i >= 0)
  811: 		kbd = kbd_get_keyboard(i);
  812: 	if (kbd != NULL)
  813: 	{
  814: 		reset_keyboard = 1;	/* ok to reset the keyboard */
  815: 		kbd_code_init();
  816: 		return;
  817: 	}
  818: 	reset_keyboard = 0;
  819: 	timeout(detect_kbd, (void *)unit, hz*2);
  820: }
  821: 
  822: int
  823: pcevent(keyboard_t *thiskbd, int event, void *arg)
  824: {
  825: 	int unit = (int)arg;
  826: 
  827: 	if (thiskbd != kbd)
  828: 		return EINVAL;		/* shouldn't happen */
  829: 
  830: 	switch (event) {
  831: 	case KBDIO_KEYINPUT:
  832: 		pcrint(unit);
  833: 		return 0;
  834: 	case KBDIO_UNLOADING:
  835: 		reset_keyboard = 0;
  836: 		kbd = NULL;
  837: 		kbd_release(thiskbd, (void *)&kbd);
  838: 		timeout(detect_kbd, (void *)unit, hz*4);
  839: 		return 0;
  840: 	default:
  841: 		return EINVAL;
  842: 	}
  843: }
  844: #endif /* _DEV_KBD_KBDREG_H_ */
  845: 
  846: void
  847: pcrint(int unit)
  848: {
  849: 
  850: #if PCVT_KBD_FIFO
  851: 	u_char	dt;
  852: 	u_char	ret = -1;
  853: 
  854: # if PCVT_SLOW_INTERRUPT
  855: 	int	s;
  856: # endif
  857: 
  858: # ifdef _DEV_KBD_KBDREG_H_
  859: 	int	c;
  860: # endif
  861: 
  862: #else /* !PCVT_KBD_FIFO */
  863: 	u_char	*cp;
  864: #endif /* PCVT_KBD_FIFO */
  865: 
  866: #if PCVT_SCREENSAVER
  867: 	pcvt_scrnsv_reset();
  868: #endif /* PCVT_SCREENSAVER */
  869: 
  870: #if PCVT_KBD_FIFO
  871: 	if (kbd_polling)
  872: 	{
  873: 		sgetc(1);
  874: 		return;
  875: 	}
  876: 
  877: # ifndef _DEV_KBD_KBDREG_H_
  878: 	while (inb(CONTROLLER_CTRL) & STATUS_OUTPBF)	/* check 8042 buffer */
  879: 	{
  880: 		ret = 1;				/* got something */
  881: 
  882: 		PCVT_KBD_DELAY();			/* 7 us delay */
  883: 
  884: 		dt = inb(CONTROLLER_DATA);		/* get it 8042 data */
  885: # else 
  886: 	while ((c = (*kbdsw[kbd->kb_index]->read)(kbd, FALSE)) != -1)
  887: 	{
  888: 		ret = 1;				/* got something */
  889: 		dt = c;
  890: # endif /* _DEV_KBD_KBDREG_H_ */
  891: 
  892: 		if (pcvt_kbd_count >= PCVT_KBD_FIFO_SZ)	/* fifo overflow ? */
  893: 		{
  894: 			log (LOG_WARNING, "pcvt: keyboard buffer overflow\n");
  895: 		}
  896: 		else
  897: 		{
  898: 			pcvt_kbd_fifo[pcvt_kbd_wptr++] = dt; /* data -> fifo */
  899: 
  900: 			PCVT_DISABLE_INTR ();	/* XXX necessary ? */
  901: 			pcvt_kbd_count++;		/* update fifo count */
  902: 			PCVT_ENABLE_INTR ();
  903: 
  904: 			if (pcvt_kbd_wptr >= PCVT_KBD_FIFO_SZ)
  905: 				pcvt_kbd_wptr = 0;	/* wraparound pointer */
  906: 		}
  907: 	}
  908: 
  909: 	if (ret == 1)	/* got data from keyboard ? */
  910: 	{
  911: 		if (!pcvt_timeout_scheduled)	/* if not already active .. */
  912: 		{
  913: 			PCVT_DISABLE_INTR ();
  914: 			pcvt_timeout_scheduled = 1;	/* flag active */
  915: 			timeout(pcvt_timeout, NULL, hz / 100);	/* fire off */
  916: 			PCVT_ENABLE_INTR ();
  917: 		}
  918: 	}
  919: 
  920: #else /* !PCVT_KBD_FIFO */
  921: 
  922: 	if((cp = sgetc(1)) == 0)
  923: 		return;
  924: 
  925: 	if (kbd_polling)
  926: 		return;
  927: 
  928: 	if(!(vs[current_video_screen].openf))	/* XXX was vs[minor(dev)] */
  929: 		return;
  930: 
  931: #if PCVT_NULLCHARS
  932: 	if(*cp == '\0')
  933: 	{
  934: 		/* pass a NULL character */
  935: 		(*linesw[pcconsp->t_line].l_rint)('\0', pcconsp);
  936: 		return;
  937: 	}
  938: #endif /* PCVT_NULLCHARS */
  939: 
  940: 	while (*cp)
  941: 		(*linesw[pcconsp->t_line].l_rint)(*cp++ & 0xff, pcconsp);
  942: 
  943: #endif /* PCVT_KBD_FIFO */
  944: }
  945: 
  946: 
  947: #if PCVT_NETBSD || PCVT_FREEBSD >= 200
  948: 
  949: void
  950: pcstart(struct tty *tp)
  951: {
  952: 	struct clist *rbp;
  953: 	int s, len;
  954: 	u_char buf[PCVT_PCBURST];
  955: 
  956: 	s = spltty();
  957: 
  958: 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
  959: 		goto out;
  960: 
  961: 	tp->t_state |= TS_BUSY;
  962: 
  963: 	splx(s);
  964: 
  965: 	async_update(UPDATE_KERN);
  966: 
  967: 	rbp = &tp->t_outq;
  968: 
  969: 	/*
  970: 	 * Call q_to_b() at spltty() to ensure that the queue is empty when
  971: 	 * the loop terminates.
  972: 	 */
  973: 
  974: 	s = spltty();
  975: 
  976: 	while((len = q_to_b(rbp, buf, PCVT_PCBURST)) > 0)
  977: 	{
  978: 		if(vs[minor(tp->t_dev)].scrolling)
  979: 			sgetc(31337);
  980: 		
  981: 		/*
  982: 		 * We need to do this outside spl since it could be fairly
  983: 		 * expensive and we don't want our serial ports to overflow.
  984: 		 */
  985: 		splx(s);
  986: 		sput(&buf[0], 0, len, minor(tp->t_dev));
  987: 		s = spltty();
  988: 	}
  989: 
  990: 	tp->t_state &= ~TS_BUSY;
  991: 
  992: #ifndef TS_ASLEEP /* FreeBSD some time after 2.0.5 */
  993: 	ttwwakeup(tp);
  994: #else
  995: 	if (rbp->c_cc <= tp->t_lowat)
  996: 	{
  997: 		if (tp->t_state&TS_ASLEEP)
  998: 		{
  999: 			tp->t_state &= ~TS_ASLEEP;
 1000: 			wakeup((caddr_t)rbp);
 1001: 		}
 1002: 		selwakeup(&tp->t_wsel);
 1003: 	}
 1004: #endif
 1005: out:
 1006: 	splx(s);
 1007: }
 1008: 
 1009: void
 1010: pcstop(struct tty *tp, int flag)
 1011: {
 1012: }
 1013: 
 1014: #else /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
 1015: 
 1016: void
 1017: pcstart(struct tty *tp)
 1018: {
 1019: 	int s;
 1020: 	unsigned char c;
 1021: 
 1022: 	s = spltty();
 1023: 
 1024: 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
 1025: 	{
 1026: 		goto out;
 1027: 	}
 1028: 
 1029: 	for(;;)
 1030: 	{
 1031: 
 1032: #if !(PCVT_FREEBSD > 114)
 1033: 
 1034: #if !(PCVT_FREEBSD > 111)
 1035: 		if (RB_LEN(&tp->t_out) <= tp->t_lowat)
 1036: #else
 1037: 		if (RB_LEN(tp->t_out) <= tp->t_lowat)
 1038: #endif
 1039: 		{
 1040: 			if (tp->t_state&TS_ASLEEP)
 1041: 			{
 1042: 				tp->t_state &= ~TS_ASLEEP;
 1043: #if !(PCVT_FREEBSD > 111)
 1044: 				wakeup((caddr_t)&tp->t_out);
 1045: #else
 1046: 				wakeup((caddr_t)tp->t_out);
 1047: #endif
 1048: 			}
 1049: 
 1050: 			if (tp->t_wsel)
 1051: 			{
 1052: 				selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
 1053: 				tp->t_wsel = 0;
 1054: 				tp->t_state &= ~TS_WCOLL;
 1055: 			}
 1056: 		}
 1057: 
 1058: #else /* PCVT_FREEBSD > 114 */
 1059: 		if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT)
 1060: 		    || tp->t_wsel) {
 1061: 			ttwwakeup(tp);
 1062: 		}
 1063: #endif /* !PCVT_FREEBSD > 114 */
 1064: 
 1065: #if !(PCVT_FREEBSD > 111)
 1066: 		if (RB_LEN(&tp->t_out) == 0)
 1067: #else
 1068: 		if (RB_LEN(tp->t_out) == 0)
 1069: #endif
 1070: 		{
 1071: 			goto out;
 1072: 		}
 1073: 
 1074: #if !(PCVT_FREEBSD > 111)
 1075: 		c = getc(&tp->t_out);
 1076: #else
 1077: 		c = getc(tp->t_out);
 1078: #endif
 1079: 
 1080: 		tp->t_state |= TS_BUSY;	/* patch from Frank Maclachlan */
 1081: 		splx(s);
 1082: 		sput(&c, 0, 1, minor(tp->t_dev));
 1083: 		spltty();
 1084: 		tp->t_state &= ~TS_BUSY; /* patch from Frank Maclachlan */
 1085: 	}
 1086: out:
 1087: 	splx(s);
 1088: }
 1089: 
 1090: #endif /* PCVT_NETBSD || PCVT_FREEBSD >= 200 */
 1091: 
 1092: /*---------------------------------------------------------------------------*
 1093:  *		/dev/console
 1094:  *---------------------------------------------------------------------------*/
 1095: 
 1096: #if !PCVT_NETBSD	/* has moved to cons.c in netbsd-current */
 1097: void
 1098: consinit()		/* init for kernel messages during boot */
 1099: {
 1100: }
 1101: #endif /* PCVT_NETBSD */
 1102: 
 1103: #if PCVT_FREEBSD > 205
 1104: static void
 1105: #else
 1106: int
 1107: #endif
 1108: pccnprobe(struct consdev *cp)
 1109: {
 1110: 	int unit = 0;
 1111: 	int i;
 1112: 
 1113: 	/* See if this driver is disabled in probe hint. */ 
 1114: 	if (resource_int_value("vt", unit, "disabled", &i) == 0 && i) {
 1115: 		cp->cn_pri = CN_DEAD;
 1116: 		return;
 1117: 	}
 1118: 
 1119: #ifdef _DEV_KBD_KBDREG_H_
 1120: 	kbd_configure(KB_CONF_PROBE_ONLY);
 1121: 	if (kbd_find_keyboard("*", unit) < 0)
 1122: 	{
 1123: 		cp->cn_pri = CN_DEAD;
 1124: 		return;
 1125: 	}
 1126: #endif /* _DEV_KBD_KBDREG_H_ */
 1127: 
 1128: 	/* initialize required fields */
 1129: 
 1130: 	cp->cn_dev = makedev(CDEV_MAJOR, 0);
 1131: 	cp->cn_pri = CN_INTERNAL;
 1132: 
 1133: #if !PCVT_NETBSD
 1134: 
 1135: #if !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200)
 1136: 	cp->cn_tp = &pccons[0];
 1137: #else
 1138: 	cp->cn_tp = pccons[0];
 1139: #endif /* !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) */
 1140: 
 1141: #endif /* !PCVT_NETBSD */
 1142: 
 1143: #if PCVT_FREEBSD <= 205
 1144: 	return 1;
 1145: #endif
 1146: }
 1147: 
 1148: #if PCVT_FREEBSD > 205
 1149: static void
 1150: #else
 1151: int
 1152: #endif
 1153: pccninit(struct consdev *cp)
 1154: {
 1155: 	int unit = 0;
 1156: 	int i;
 1157: 
 1158: 	pcvt_is_console = 1;
 1159: 
 1160: #ifdef _DEV_KBD_KBDREG_H_
 1161: 	/*
 1162: 	 * Don't reset the keyboard via `kbdio' just yet.
 1163: 	 * The system clock has not been calibrated...
 1164: 	 */
 1165: 	reset_keyboard = 0;
 1166: 
 1167: 	if (kbd)
 1168: 	{
 1169: 		kbd_release(kbd, (void *)&kbd);
 1170: 		kbd = NULL;
 1171: 	}
 1172: 	i = kbd_allocate("*", -1, (void *)&kbd, pcevent, (void *)unit);
 1173: 	if (i >= 0)
 1174: 		kbd = kbd_get_keyboard(i);
 1175: 
 1176: #if PCVT_SCANSET == 2
 1177: 	/*
 1178: 	 * Turn off scancode translation early so that UserConfig 
 1179: 	 * and DDB can read the keyboard.
 1180: 	 */
 1181: 	if (kbd)
 1182: 	{
 1183: 		empty_both_buffers(*(KBDC *)kbd->kb_data, 10);
 1184: 		set_controller_command_byte(*(KBDC *)kbd->kb_data,
 1185: 					    KBD_TRANSLATION, 0);
 1186: 	}
 1187: #endif /* PCVT_SCANSET == 2 */
 1188: 
 1189: #endif /* _DEV_KBD_KBDREG_H_ */
 1190: 
 1191: #if PCVT_FREEBSD <= 205
 1192: 	return 0;
 1193: #endif
 1194: }
 1195: 
 1196: static void
 1197: pccnterm(struct consdev *cp)
 1198: {
 1199: #ifdef _DEV_KBD_KBDREG_H_
 1200: 	if (kbd)
 1201: 	{
 1202: 		kbd_release(kbd, (void *)&kbd);
 1203: 		kbd = NULL;
 1204: 	}
 1205: #endif /* _DEV_KBD_KBDREG_H_ */
 1206: }
 1207: 
 1208: #if PCVT_FREEBSD > 205
 1209: static void
 1210: #else
 1211: int
 1212: #endif
 1213: pccnputc(Dev_t dev, U_char c)
 1214: {
 1215: 
 1216: #if PCVT_SW0CNOUTP
 1217: 
 1218: 	if(current_video_screen != 0)
 1219: 	{
 1220: 
 1221: #if !PCVT_USL_VT_COMPAT
 1222: 		vgapage(0);
 1223: #else
 1224: 		switch_screen(0, 0);
 1225: #endif /* !PCVT_USL_VT_COMPAT */
 1226: 
 1227: 	}
 1228: 
 1229: #endif /* PCVT_SW0CNOUTP */
 1230: 
 1231: 	if (c == '\n')
 1232: 		sput("\r", 1, 1, 0);
 1233: 
 1234: 	sput((char *) &c, 1, 1, 0);
 1235: 
 1236:  	async_update(UPDATE_KERN);
 1237: 
 1238: #if PCVT_FREEBSD <= 205
 1239: 	return 0;
 1240: #endif
 1241: }
 1242: 
 1243: static int
 1244: pccngetc(Dev_t dev)
 1245: {
 1246: 	int s;
 1247: 	static u_char *cp, cbuf[4]; /* Temp buf for multi-char key sequence. */
 1248: 	u_char c;
 1249: 
 1250: #ifdef XSERVER
 1251: 
 1252: #if !PCVT_USL_VT_COMPAT
 1253: 	if (pcvt_xmode)
 1254: 		return 0;
 1255: #else /* !PCVT_USL_VT_COMPAT */
 1256: 	if (pcvt_kbd_raw)
 1257: 		return 0;
 1258: #endif /* !PCVT_USL_VT_COMPAT */
 1259: 
 1260: #endif /* XSERVER */
 1261: 
 1262: 	if (cp && *cp)
 1263: 		/*
 1264: 		 * We still have a pending key sequence, e.g.
 1265: 		 * from an arrow key.  Deliver this one first.
 1266: 		 */
 1267: 		return (*cp++);
 1268: 
 1269: #ifdef _DEV_KBD_KBDREG_H_
 1270: 	if (kbd == NULL)
 1271: 		return 0;
 1272: #endif	
 1273: 
 1274: 	s = spltty();		/* block pcrint while we poll */
 1275: 	kbd_polling = 1;
 1276: #ifdef _DEV_KBD_KBDREG_H_
 1277: 	(*kbdsw[kbd->kb_index]->enable)(kbd);
 1278: #endif	
 1279: 	cp = sgetc(0);
 1280: #ifdef _DEV_KBD_KBDREG_H_
 1281: 	(*kbdsw[kbd->kb_index]->disable)(kbd);
 1282: #endif	
 1283: 	kbd_polling = 0;
 1284: 	splx(s);
 1285: 	c = *cp++;
 1286: 	if (c && *cp) {
 1287: 		/* Preserve the multi-char sequence for the next call. */
 1288: 		bcopy(cp, cbuf, 3); /* take care for a trailing '\0' */
 1289: 		cp = cbuf;
 1290: 	} else
 1291: 		cp = 0;
 1292: 
 1293: #if ! (PCVT_FREEBSD >= 201)
 1294: 	/* this belongs to cons.c */
 1295: 	if (c == '\r')
 1296: 		c = '\n';
 1297: #endif /* ! (PCVT_FREEBSD >= 201) */
 1298: 
 1299: 	return c;
 1300: }
 1301: 
 1302: #if PCVT_FREEBSD >= 200
 1303: static int
 1304: pccncheckc(Dev_t dev)
 1305: {
 1306: 	char *cp;
 1307: 	int x;
 1308: 
 1309: #ifdef _DEV_KBD_KBDREG_H_
 1310: 	if (kbd == NULL)
 1311: 		return 0;
 1312: #endif	
 1313: 
 1314: 	x = spltty();
 1315: 	kbd_polling = 1;
 1316: #ifdef _DEV_KBD_KBDREG_H_
 1317: 	(*kbdsw[kbd->kb_index]->enable)(kbd);
 1318: #endif	
 1319: 	cp = sgetc(1);
 1320: #ifdef _DEV_KBD_KBDREG_H_
 1321: 	(*kbdsw[kbd->kb_index]->disable)(kbd);
 1322: #endif	
 1323: 	kbd_polling = 0;
 1324: 	splx(x);
 1325: 	return (cp == NULL ? -1 : *cp);
 1326: }
 1327: #endif /* PCVT_FREEBSD >= 200 */
 1328: 
 1329: #if PCVT_NETBSD >= 100
 1330: void
 1331: pccnpollc(Dev_t dev, int on)
 1332: {
 1333: 	kbd_polling = on;
 1334: 	if (!on) {
 1335: 		int s;
 1336: 
 1337: 		/*
 1338: 		 * If disabling polling, make sure there are no bytes left in
 1339: 		 * the FIFO, holding up the interrupt line.  Otherwise we
 1340: 		 * won't get any further interrupts.
 1341: 		 */
 1342: 		s = spltty();
 1343: 		pcrint();
 1344: 		splx(s);
 1345: 	}
 1346: }
 1347: #endif /* PCVT_NETBSD >= 100 */
 1348: 
 1349: /*---------------------------------------------------------------------------*
 1350:  *	Set line parameters
 1351:  *---------------------------------------------------------------------------*/
 1352: int
 1353: pcparam(struct tty *tp, struct termios *t)
 1354: {
 1355: 	int cflag = t->c_cflag;
 1356: 
 1357:         /* and copy to tty */
 1358: 
 1359:         tp->t_ispeed = t->c_ispeed;
 1360:         tp->t_ospeed = t->c_ospeed;
 1361:         tp->t_cflag = cflag;
 1362: 
 1363: 	return(0);
 1364: }
 1365: 
 1366: /*----------------------------------------------------------------------*
 1367:  *	read initial VGA palette (as stored by VGA ROM BIOS) into
 1368:  *	palette save area
 1369:  *----------------------------------------------------------------------*/
 1370: void
 1371: vgapelinit(void)
 1372: {
 1373: 	unsigned idx;
 1374: 	struct rgb *val;
 1375: 
 1376: 	/* first, read all and store to first screen's save buffer */
 1377: 	for(idx = 0, val = vs[0].palette; idx < NVGAPEL; idx++, val++)
 1378: 		vgapaletteio(idx, val, 0 /* read it */);
 1379: 
 1380: 	/* now, duplicate for remaining screens */
 1381: 	for(idx = 1; idx < PCVT_NSCREENS; idx++)
 1382: 		bcopy(vs[0].palette, vs[idx].palette,
 1383: 		      NVGAPEL * sizeof(struct rgb));
 1384: }
 1385: 
 1386: #if defined XSERVER && !PCVT_USL_VT_COMPAT
 1387: /*----------------------------------------------------------------------*
 1388:  *	initialize for X mode
 1389:  *	i.e.: grant current process (the X server) all IO privileges,
 1390:  *	and mark in static variable so other hooks can test for it,
 1391:  *	save all loaded fonts and screen pages to pageable buffers;
 1392:  *	if parameter `on' is false, the same procedure is done reverse.
 1393:  *----------------------------------------------------------------------*/
 1394: static int
 1395: pcvt_xmode_set(int on, struct thread *td)
 1396: {
 1397: 	static unsigned char *saved_fonts[NVGAFONTS];
 1398: 
 1399: #if PCVT_SCREENSAVER
 1400: 	static unsigned saved_scrnsv_tmo = 0;
 1401: #endif /* PCVT_SCREENSAVER */
 1402: 
 1403: #if (PCVT_NETBSD > 9) || (PCVT_FREEBSD > 102)
 1404: 	struct trapframe *fp;
 1405: #else
 1406: 	struct syscframe *fp;
 1407: #endif /* PCVT_NETBSD > 9 */
 1408: 
 1409: 	int error, i;
 1410: 
 1411: 	/* X will only run on VGA and Hercules adaptors */
 1412: 
 1413: 	if(adaptor_type != VGA_ADAPTOR && adaptor_type != MDA_ADAPTOR)
 1414: 		return (EINVAL);
 1415: 
 1416: #if PCVT_NETBSD > 9
 1417: 	fp = (struct trapframe *)p->p_regs;
 1418: #else
 1419: 	fp = (struct syscframe *)p->p_regs;
 1420: #endif /* PCVT_NETBSD > 9 */
 1421: 
 1422: 	if(on)
 1423: 	{
 1424: 		/*
 1425: 		 * Test whether the calling process has super-user privileges
 1426: 		 * and we're in insecure mode.
 1427: 		 * This prevents us from granting the potential security hole
 1428: 		 * `IO priv' to insufficiently privileged processes.
 1429: 		 */
 1430: 		error = suser(td);
 1431: 		if (error != 0)
 1432: 			return (error);
 1433: 		if (securelevel > 0)
 1434: 			return (EPERM);
 1435: 
 1436: 		if(pcvt_xmode)
 1437: 			return 0;
 1438: 
 1439: 		pcvt_xmode = pcvt_kbd_raw = 1;
 1440: 
 1441: 		for(i = 0; i < totalfonts; i++)
 1442: 		{
 1443: 			if(vgacs[i].loaded)
 1444: 			{
 1445: 				saved_fonts[i] = (unsigned char *)
 1446: 					malloc(32 * 256, M_DEVBUF, M_WAITOK);
 1447: 				if(saved_fonts[i] == 0)
 1448: 				{
 1449: 					printf(
 1450: 				  "pcvt_xmode_set: no font buffer available\n");
 1451: 					return (EAGAIN);
 1452: 				}
 1453: 				else
 1454: 				{
 1455: 					vga_move_charset(i, saved_fonts[i], 1);
 1456: 				}
 1457: 			}
 1458: 			else
 1459: 			{
 1460: 				saved_fonts[i] = 0;
 1461: 			}
 1462: 		}
 1463: 
 1464: #if PCVT_SCREENSAVER
 1465: 		if(saved_scrnsv_tmo = scrnsv_timeout)
 1466: 			pcvt_set_scrnsv_tmo(0);	/* turn it off */
 1467: #endif /* PCVT_SCREENSAVER */
 1468: 
 1469: 		async_update(UPDATE_STOP);	/* turn off */
 1470: 
 1471: 		/* disable text output and save screen contents */
 1472: 		/* video board memory -> kernel memory */
 1473: 
 1474: 		bcopy(vsp->Crtat, vsp->Memory,
 1475: 		       vsp->screen_rowsize * vsp->maxcol * CHR);
 1476: 
 1477: 		vsp->Crtat = vsp->Memory;	/* operate in memory now */
 1478: 
 1479: #ifndef _DEV_KBD_KBDREG_H_
 1480: 
 1481: #if PCVT_SCANSET == 2
 1482: 		/* put keyboard to return ancient PC scan codes */
 1483: 		kbc_8042cmd(CONTR_WRITE);
 1484: #if PCVT_USEKBDSEC		/* security enabled */
 1485: 		outb(CONTROLLER_DATA,
 1486: 		 (COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
 1487: #else				/* security disabled */
 1488: 		outb(CONTROLLER_DATA,
 1489: 		 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN|COMMAND_PCSCAN));
 1490: #endif /* PCVT_USEKBDSEC */
 1491: #endif /* PCVT_SCANSET == 2 */
 1492: 
 1493: #else /* _DEV_KBD_KBDREG_H_ */
 1494: 
 1495: #if PCVT_SCANSET == 2
 1496: 		/* put keyboard to return ancient PC scan codes */
 1497: 		set_controller_command_byte(*(KBDC *)kbd->kb_data, 
 1498: 			KBD_TRANSLATION, KBD_TRANSLATION); 
 1499: #endif /* PCVT_SCANSET == 2 */
 1500: 
 1501: #endif /* !_DEV_KBD_KBDREG_H_ */
 1502: 
 1503: #if PCVT_NETBSD > 9
 1504: 		fp->tf_eflags |= PSL_IOPL;
 1505: #else
 1506: 		fp->sf_eflags |= PSL_IOPL;
 1507: #endif /* PCVT_NETBSD > 9 */
 1508: 
 1509: 	}
 1510: 	else
 1511: 	{
 1512: 		if(!pcvt_xmode)		/* verify if in X */
 1513: 			return 0;
 1514: 
 1515: 		pcvt_xmode = pcvt_kbd_raw = 0;
 1516: 
 1517: 		for(i = 0; i < totalfonts; i++)
 1518: 		{
 1519: 			if(saved_fonts[i])
 1520: 			{
 1521: 				vga_move_charset(i, saved_fonts[i], 0);
 1522: 				free(saved_fonts[i], M_DEVBUF);
 1523: 				saved_fonts[i] = 0;
 1524: 			}
 1525: 		}
 1526: 
 1527: #if PCVT_NETBSD > 9
 1528: 		fp->tf_eflags &= ~PSL_IOPL;
 1529: #else
 1530: 		fp->sf_eflags &= ~PSL_IOPL;
 1531: #endif /* PCVT_NETBSD > 9 */
 1532: 
 1533: #if PCVT_SCREENSAVER
 1534: 		if(saved_scrnsv_tmo)
 1535: 			pcvt_set_scrnsv_tmo(saved_scrnsv_tmo);
 1536: #endif /* PCVT_SCREENSAVER */
 1537: 
 1538: #ifndef _DEV_KBD_KBDREG_H_
 1539: 
 1540: #if PCVT_SCANSET == 2
 1541: 		kbc_8042cmd(CONTR_WRITE);
 1542: #if PCVT_USEKBDSEC		/* security enabled */
 1543: 		outb(CONTROLLER_DATA,
 1544: 		 (COMMAND_SYSFLG|COMMAND_IRQEN));
 1545: #else				/* security disabled */
 1546: 		outb(CONTROLLER_DATA,
 1547: 		 (COMMAND_INHOVR|COMMAND_SYSFLG|COMMAND_IRQEN));
 1548: #endif /* PCVT_USEKBDSEC */
 1549: #endif /* PCVT_SCANSET == 2 */
 1550: 
 1551: #else /* _DEV_KBD_KBDREG_H_ */
 1552: 
 1553: #if PCVT_SCANSET == 2
 1554: 		set_controller_command_byte(*(KBDC *)kbd->kb_data,
 1555: 			KBD_TRANSLATION, 0);
 1556: #endif /* PCVT_SCANSET == 2 */
 1557: 
 1558: #endif /* !_DEV_KBD_KBDREG_H_ */
 1559: 
 1560: 		if(adaptor_type == MDA_ADAPTOR)
 1561: 		{
 1562: 		    /*
 1563: 		     * Due to the fact that HGC registers are write-only,
 1564: 		     * the Xserver can only make guesses about the state
 1565: 		     * the HGC adaptor has been before turning on X mode.
 1566: 		     * Thus, the display must be re-enabled now, and the
 1567: 		     * cursor shape and location restored.
 1568: 		     */
 1569: 		    outb(GN_DMCNTLM, 0x28); /* enable display, text mode */
 1570: 		    outb(addr_6845, CRTC_CURSORH); /* select high register */
 1571: 		    outb(addr_6845+1,
 1572: 			 ((vsp->Crtat + vsp->cur_offset) - Crtat) >> 8);
 1573: 		    outb(addr_6845, CRTC_CURSORL); /* select low register */
 1574: 		    outb(addr_6845+1,
 1575: 			 ((vsp->Crtat + vsp->cur_offset) - Crtat));
 1576: 
 1577: 		    outb(addr_6845, CRTC_CURSTART); /* select high register */
 1578: 		    outb(addr_6845+1, vsp->cursor_start);
 1579: 		    outb(addr_6845, CRTC_CUREND); /* select low register */
 1580: 		    outb(addr_6845+1, vsp->cursor_end);
 1581: 		  }
 1582: 
 1583: 		/* restore screen and re-enable text output */
 1584: 		/* kernel memory -> video board memory */
 1585: 
 1586: 		bcopy(vsp->Memory, Crtat,
 1587: 		       vsp->screen_rowsize * vsp->maxcol * CHR);
 1588: 
 1589: 		vsp->Crtat = Crtat;	/* operate on-screen now */
 1590: 
 1591: 		/* set crtc screen memory start address */
 1592: 
 1593: 		outb(addr_6845, CRTC_STARTADRH);
 1594: 		outb(addr_6845+1, (vsp->Crtat - Crtat) >> 8);
 1595: 		outb(addr_6845, CRTC_STARTADRL);
 1596: 		outb(addr_6845+1, (vsp->Crtat - Crtat));
 1597: 
 1598: 		async_update(UPDATE_START);
 1599: 	}
 1600: 	return 0;
 1601: }
 1602: #endif	/* XSERVER && !PCVT_USL_VT_COMPAT */
 1603: 
 1604: #endif	/* NVT > 0 */
 1605: 
 1606: /*-------------------------- E O F -------------------------------------*/