Home | History | Annotate | Line # | Download | only in dev
kd.c revision 1.1.1.1.10.1
      1  1.1.1.1.10.1  thorpej /*	$NetBSD: kd.c,v 1.1.1.1.10.1 1999/06/21 01:02:31 thorpej Exp $	*/
      2           1.1      eeh 
      3           1.1      eeh /*-
      4           1.1      eeh  * Copyright (c) 1996 The NetBSD Foundation, Inc.
      5           1.1      eeh  * All rights reserved.
      6           1.1      eeh  *
      7           1.1      eeh  * This code is derived from software contributed to The NetBSD Foundation
      8           1.1      eeh  * by Gordon W. Ross.
      9           1.1      eeh  *
     10           1.1      eeh  * Redistribution and use in source and binary forms, with or without
     11           1.1      eeh  * modification, are permitted provided that the following conditions
     12           1.1      eeh  * are met:
     13           1.1      eeh  * 1. Redistributions of source code must retain the above copyright
     14           1.1      eeh  *    notice, this list of conditions and the following disclaimer.
     15           1.1      eeh  * 2. Redistributions in binary form must reproduce the above copyright
     16           1.1      eeh  *    notice, this list of conditions and the following disclaimer in the
     17           1.1      eeh  *    documentation and/or other materials provided with the distribution.
     18           1.1      eeh  * 3. All advertising materials mentioning features or use of this software
     19           1.1      eeh  *    must display the following acknowledgement:
     20           1.1      eeh  *        This product includes software developed by the NetBSD
     21           1.1      eeh  *        Foundation, Inc. and its contributors.
     22           1.1      eeh  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23           1.1      eeh  *    contributors may be used to endorse or promote products derived
     24           1.1      eeh  *    from this software without specific prior written permission.
     25           1.1      eeh  *
     26           1.1      eeh  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27           1.1      eeh  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28           1.1      eeh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29           1.1      eeh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30           1.1      eeh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31           1.1      eeh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32           1.1      eeh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33           1.1      eeh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34           1.1      eeh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35           1.1      eeh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36           1.1      eeh  * POSSIBILITY OF SUCH DAMAGE.
     37           1.1      eeh  */
     38           1.1      eeh 
     39           1.1      eeh /*
     40           1.1      eeh  * Keyboard/Display device.
     41           1.1      eeh  *
     42           1.1      eeh  * This driver exists simply to provide a tty device that
     43           1.1      eeh  * the indirect console driver can point to.
     44           1.1      eeh  * The kbd driver sends its input here.
     45           1.1      eeh  * Output goes to the screen via PROM printf.
     46           1.1      eeh  */
     47           1.1      eeh 
     48           1.1      eeh #include <sys/param.h>
     49           1.1      eeh #include <sys/proc.h>
     50           1.1      eeh #include <sys/systm.h>
     51           1.1      eeh #include <sys/ioctl.h>
     52           1.1      eeh #include <sys/tty.h>
     53           1.1      eeh #include <sys/file.h>
     54           1.1      eeh #include <sys/conf.h>
     55           1.1      eeh #include <sys/device.h>
     56           1.1      eeh 
     57           1.1      eeh #include <machine/openfirm.h>
     58           1.1      eeh #include <machine/eeprom.h>
     59           1.1      eeh #include <machine/psl.h>
     60           1.1      eeh #include <machine/cpu.h>
     61           1.1      eeh #include <machine/kbd.h>
     62           1.1      eeh #include <machine/autoconf.h>
     63           1.1      eeh #include <machine/conf.h>
     64           1.1      eeh 
     65           1.1      eeh #ifdef RASTERCONSOLE
     66           1.1      eeh #include <machine/fbio.h>
     67           1.1      eeh #include <machine/fbvar.h>
     68           1.1      eeh #endif
     69           1.1      eeh 
     70           1.1      eeh 
     71           1.1      eeh #include <dev/cons.h>
     72           1.1      eeh #include <dev/sun/kbd_xlate.h>
     73           1.1      eeh #include <sparc64/dev/cons.h>
     74           1.1      eeh 
     75           1.1      eeh struct	tty *fbconstty = 0;	/* tty structure for frame buffer console */
     76           1.1      eeh int cnrom __P((void));
     77           1.1      eeh void cnrint __P((void));
     78           1.1      eeh 
     79           1.1      eeh #define	KDMAJOR 1
     80           1.1      eeh #define PUT_WSIZE	64
     81           1.1      eeh 
     82           1.1      eeh struct kd_softc {
     83           1.1      eeh 	struct	device kd_dev;		/* required first: base device */
     84           1.1      eeh 	struct  tty *kd_tty;
     85           1.1      eeh 	int rows, cols;
     86           1.1      eeh };
     87           1.1      eeh 
     88           1.1      eeh /*
     89           1.1      eeh  * There is no point in pretending there might be
     90           1.1      eeh  * more than one keyboard/display device.
     91           1.1      eeh  */
     92           1.1      eeh static struct kd_softc kd_softc;
     93           1.1      eeh static int kd_is_console;
     94           1.1      eeh 
     95           1.1      eeh static int kdparam(struct tty *, struct termios *);
     96           1.1      eeh static void kdstart(struct tty *);
     97           1.1      eeh 
     98           1.1      eeh int	rom_console_input;	/* when set, hardclock calls cnrom() */
     99           1.1      eeh int	cons_ocount;		/* output byte count */
    100           1.1      eeh 
    101           1.1      eeh /* Now talking directly to the zs, so this is not needed. */
    102           1.1      eeh int
    103           1.1      eeh cnrom()
    104           1.1      eeh {
    105           1.1      eeh   return (0);
    106           1.1      eeh }
    107           1.1      eeh void
    108           1.1      eeh cnrint()
    109           1.1      eeh {
    110           1.1      eeh }
    111           1.1      eeh 
    112           1.1      eeh /*
    113           1.1      eeh  * This is called by kbd_attach()
    114           1.1      eeh  * XXX - Make this a proper child of kbd?
    115           1.1      eeh  */
    116           1.1      eeh void
    117           1.1      eeh kd_init(unit)
    118           1.1      eeh 	int unit;
    119           1.1      eeh {
    120           1.1      eeh 	struct kd_softc *kd;
    121           1.1      eeh 	struct tty *tp;
    122  1.1.1.1.10.1  thorpej 	int i;
    123  1.1.1.1.10.1  thorpej 	char *prop;
    124  1.1.1.1.10.1  thorpej 
    125           1.1      eeh 
    126           1.1      eeh 	if (unit != 0)
    127           1.1      eeh 		return;
    128           1.1      eeh 	kd = &kd_softc; 	/* XXX */
    129           1.1      eeh 
    130           1.1      eeh 	tp = ttymalloc();
    131           1.1      eeh 	tp->t_oproc = kdstart;
    132           1.1      eeh 	tp->t_param = kdparam;
    133           1.1      eeh 	tp->t_dev = makedev(KDMAJOR, unit);
    134           1.1      eeh 
    135           1.1      eeh #if 1	/* XXX - Why? */
    136           1.1      eeh 	clalloc(&tp->t_rawq, 1024, 1);
    137           1.1      eeh 	clalloc(&tp->t_canq, 1024, 1);
    138           1.1      eeh 	/* output queue doesn't need quoting */
    139           1.1      eeh 	clalloc(&tp->t_outq, 1024, 0);
    140           1.1      eeh #endif
    141           1.1      eeh 
    142           1.1      eeh 	tty_attach(tp);
    143           1.1      eeh 	kd->kd_tty = tp;
    144           1.1      eeh 
    145           1.1      eeh 	/*
    146           1.1      eeh 	 * get the console struct winsize.
    147           1.1      eeh 	 */
    148           1.1      eeh 	if (kd_is_console) {
    149           1.1      eeh 		fbconstty = tp;
    150           1.1      eeh #ifdef RASTERCONSOLE
    151           1.1      eeh 		kd->rows = fbrcons_rows();
    152           1.1      eeh 		kd->cols = fbrcons_cols();
    153           1.1      eeh #endif
    154           1.1      eeh 	}
    155           1.1      eeh 
    156  1.1.1.1.10.1  thorpej 	if (kd->rows == 0 &&
    157  1.1.1.1.10.1  thorpej 	    (prop = getpropstring(optionsnode, "screen-#rows"))) {
    158  1.1.1.1.10.1  thorpej 		i = 0;
    159  1.1.1.1.10.1  thorpej 		while (*prop != '\0')
    160  1.1.1.1.10.1  thorpej 			i = i * 10 + *prop++ - '0';
    161  1.1.1.1.10.1  thorpej 		kd->rows = (unsigned short)i;
    162  1.1.1.1.10.1  thorpej 	}
    163  1.1.1.1.10.1  thorpej 	if (kd->cols == 0 &&
    164  1.1.1.1.10.1  thorpej 	    (prop = getpropstring(optionsnode, "screen-#columns"))) {
    165  1.1.1.1.10.1  thorpej 		i = 0;
    166  1.1.1.1.10.1  thorpej 		while (*prop != '\0')
    167  1.1.1.1.10.1  thorpej 			i = i * 10 + *prop++ - '0';
    168  1.1.1.1.10.1  thorpej 		kd->cols = (unsigned short)i;
    169           1.1      eeh 	}
    170           1.1      eeh 	return;
    171           1.1      eeh }
    172           1.1      eeh 
    173           1.1      eeh struct tty *
    174           1.1      eeh kdtty(dev)
    175           1.1      eeh 	dev_t dev;
    176           1.1      eeh {
    177           1.1      eeh 	struct kd_softc *kd;
    178           1.1      eeh 
    179           1.1      eeh 	kd = &kd_softc; 	/* XXX */
    180           1.1      eeh 	return (kd->kd_tty);
    181           1.1      eeh }
    182           1.1      eeh 
    183           1.1      eeh int
    184           1.1      eeh kdopen(dev, flag, mode, p)
    185           1.1      eeh 	dev_t dev;
    186           1.1      eeh 	int flag, mode;
    187           1.1      eeh 	struct proc *p;
    188           1.1      eeh {
    189           1.1      eeh 	struct kd_softc *kd;
    190           1.1      eeh 	int error, s, unit;
    191           1.1      eeh 	struct tty *tp;
    192           1.1      eeh 
    193           1.1      eeh 	unit = minor(dev);
    194           1.1      eeh 	if (unit != 0)
    195           1.1      eeh 		return ENXIO;
    196           1.1      eeh 	kd = &kd_softc; 	/* XXX */
    197           1.1      eeh 	tp = kd->kd_tty;
    198           1.1      eeh 
    199           1.1      eeh 	if ((error = kbd_iopen(unit)) != 0) {
    200           1.1      eeh #ifdef	DIAGNOSTIC
    201           1.1      eeh 		printf("kd: kbd_iopen, error=%d\n", error);
    202           1.1      eeh #endif
    203           1.1      eeh 		return (error);
    204           1.1      eeh 	}
    205           1.1      eeh 
    206           1.1      eeh 	/* It's simpler to do this up here. */
    207           1.1      eeh 	if (((tp->t_state & (TS_ISOPEN | TS_XCLUDE))
    208           1.1      eeh 	     ==             (TS_ISOPEN | TS_XCLUDE))
    209           1.1      eeh 	    && (p->p_ucred->cr_uid != 0) )
    210           1.1      eeh 	{
    211           1.1      eeh 		return (EBUSY);
    212           1.1      eeh 	}
    213           1.1      eeh 
    214           1.1      eeh 	s = spltty();
    215           1.1      eeh 
    216           1.1      eeh 	if ((tp->t_state & TS_ISOPEN) == 0) {
    217           1.1      eeh 		/* First open. */
    218           1.1      eeh 		ttychars(tp);
    219           1.1      eeh 		tp->t_iflag = TTYDEF_IFLAG;
    220           1.1      eeh 		tp->t_oflag = TTYDEF_OFLAG;
    221           1.1      eeh 		tp->t_cflag = TTYDEF_CFLAG;
    222           1.1      eeh 		tp->t_lflag = TTYDEF_LFLAG;
    223           1.1      eeh 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
    224           1.1      eeh 		(void) kdparam(tp, &tp->t_termios);
    225           1.1      eeh 		ttsetwater(tp);
    226           1.1      eeh 		tp->t_winsize.ws_row = kd->rows;
    227           1.1      eeh 		tp->t_winsize.ws_col = kd->cols;
    228           1.1      eeh 		/* Flush pending input?  Clear translator? */
    229           1.1      eeh 		/* This (pseudo)device always has SOFTCAR */
    230           1.1      eeh 		tp->t_state |= TS_CARR_ON;
    231           1.1      eeh 	}
    232           1.1      eeh 
    233           1.1      eeh 	splx(s);
    234           1.1      eeh 
    235           1.1      eeh 	return ((*linesw[tp->t_line].l_open)(dev, tp));
    236           1.1      eeh }
    237           1.1      eeh 
    238           1.1      eeh int
    239           1.1      eeh kdclose(dev, flag, mode, p)
    240           1.1      eeh 	dev_t dev;
    241           1.1      eeh 	int flag, mode;
    242           1.1      eeh 	struct proc *p;
    243           1.1      eeh {
    244           1.1      eeh 	struct kd_softc *kd;
    245           1.1      eeh 	struct tty *tp;
    246           1.1      eeh 
    247           1.1      eeh 	kd = &kd_softc; 	/* XXX */
    248           1.1      eeh 	tp = kd->kd_tty;
    249           1.1      eeh 
    250           1.1      eeh 	/* XXX This is for cons.c. */
    251           1.1      eeh 	if ((tp->t_state & TS_ISOPEN) == 0)
    252           1.1      eeh 		return 0;
    253           1.1      eeh 
    254           1.1      eeh 	(*linesw[tp->t_line].l_close)(tp, flag);
    255           1.1      eeh 	ttyclose(tp);
    256           1.1      eeh 	return (0);
    257           1.1      eeh }
    258           1.1      eeh 
    259           1.1      eeh int
    260           1.1      eeh kdread(dev, uio, flag)
    261           1.1      eeh 	dev_t dev;
    262           1.1      eeh 	struct uio *uio;
    263           1.1      eeh 	int flag;
    264           1.1      eeh {
    265           1.1      eeh 	struct kd_softc *kd;
    266           1.1      eeh 	struct tty *tp;
    267           1.1      eeh 
    268           1.1      eeh 	kd = &kd_softc; 	/* XXX */
    269           1.1      eeh 	tp = kd->kd_tty;
    270           1.1      eeh 
    271           1.1      eeh 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
    272           1.1      eeh }
    273           1.1      eeh 
    274           1.1      eeh int
    275           1.1      eeh kdwrite(dev, uio, flag)
    276           1.1      eeh 	dev_t dev;
    277           1.1      eeh 	struct uio *uio;
    278           1.1      eeh 	int flag;
    279           1.1      eeh {
    280           1.1      eeh 	struct kd_softc *kd;
    281           1.1      eeh 	struct tty *tp;
    282           1.1      eeh 
    283           1.1      eeh 	kd = &kd_softc; 	/* XXX */
    284           1.1      eeh 	tp = kd->kd_tty;
    285           1.1      eeh 
    286           1.1      eeh 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
    287           1.1      eeh }
    288           1.1      eeh 
    289           1.1      eeh int
    290           1.1      eeh kdioctl(dev, cmd, data, flag, p)
    291           1.1      eeh 	dev_t dev;
    292           1.1      eeh 	u_long cmd;
    293           1.1      eeh 	caddr_t data;
    294           1.1      eeh 	int flag;
    295           1.1      eeh 	struct proc *p;
    296           1.1      eeh {
    297           1.1      eeh 	struct kd_softc *kd;
    298           1.1      eeh 	struct tty *tp;
    299           1.1      eeh 	int error;
    300           1.1      eeh 
    301           1.1      eeh 	kd = &kd_softc; 	/* XXX */
    302           1.1      eeh 	tp = kd->kd_tty;
    303           1.1      eeh 
    304           1.1      eeh 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
    305           1.1      eeh 	if (error >= 0)
    306           1.1      eeh 		return error;
    307           1.1      eeh 	error = ttioctl(tp, cmd, data, flag, p);
    308           1.1      eeh 	if (error >= 0)
    309           1.1      eeh 		return error;
    310           1.1      eeh 
    311           1.1      eeh 	/* Handle any ioctl commands specific to kbd/display. */
    312           1.1      eeh 	/* XXX - Send KB* ioctls to kbd module? */
    313           1.1      eeh 	/* XXX - Send FB* ioctls to fb module?  */
    314           1.1      eeh 
    315           1.1      eeh 	return ENOTTY;
    316           1.1      eeh }
    317           1.1      eeh 
    318           1.1      eeh void
    319           1.1      eeh kdstop(tp, flag)
    320           1.1      eeh 	struct tty *tp;
    321           1.1      eeh 	int flag;
    322           1.1      eeh {
    323           1.1      eeh 
    324           1.1      eeh }
    325           1.1      eeh 
    326           1.1      eeh 
    327           1.1      eeh static int
    328           1.1      eeh kdparam(tp, t)
    329           1.1      eeh 	struct tty *tp;
    330           1.1      eeh 	struct termios *t;
    331           1.1      eeh {
    332           1.1      eeh 	/* XXX - These are ignored... */
    333           1.1      eeh 	tp->t_ispeed = t->c_ispeed;
    334           1.1      eeh 	tp->t_ospeed = t->c_ospeed;
    335           1.1      eeh 	tp->t_cflag = t->c_cflag;
    336           1.1      eeh 	return 0;
    337           1.1      eeh }
    338           1.1      eeh 
    339           1.1      eeh 
    340           1.1      eeh static void kd_later(void*);
    341           1.1      eeh static void kd_putfb(struct tty *);
    342           1.1      eeh 
    343           1.1      eeh static void
    344           1.1      eeh kdstart(tp)
    345           1.1      eeh 	struct tty *tp;
    346           1.1      eeh {
    347           1.1      eeh 	struct clist *cl;
    348           1.1      eeh 	register int s;
    349           1.1      eeh 
    350           1.1      eeh 	s = spltty();
    351           1.1      eeh 	if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT))
    352           1.1      eeh 		goto out;
    353           1.1      eeh 
    354           1.1      eeh 	cl = &tp->t_outq;
    355           1.1      eeh 	if (cl->c_cc) {
    356           1.1      eeh 		if (kd_is_console) {
    357           1.1      eeh 			tp->t_state |= TS_BUSY;
    358           1.1      eeh 			if ((s & PSR_PIL) == 0) {
    359           1.1      eeh 				/* called at level zero - update screen now. */
    360           1.1      eeh 				(void) splsoftclock();
    361           1.1      eeh 				kd_putfb(tp);
    362           1.1      eeh 				(void) spltty();
    363           1.1      eeh 				tp->t_state &= ~TS_BUSY;
    364           1.1      eeh 			} else {
    365           1.1      eeh 				/* called at interrupt level - do it later */
    366           1.1      eeh 				timeout(kd_later, (void*)tp, 0);
    367           1.1      eeh 			}
    368           1.1      eeh 		} else {
    369           1.1      eeh 			/*
    370           1.1      eeh 			 * This driver uses the PROM for writing the screen,
    371           1.1      eeh 			 * and that only works if this is the console device.
    372           1.1      eeh 			 * If this is not the console, just flush the output.
    373           1.1      eeh 			 * Sorry.  (In that case, use xdm instead of getty.)
    374           1.1      eeh 			 */
    375           1.1      eeh 			ndflush(cl, cl->c_cc);
    376           1.1      eeh 		}
    377           1.1      eeh 	}
    378           1.1      eeh 	if (cl->c_cc <= tp->t_lowat) {
    379           1.1      eeh 		if (tp->t_state & TS_ASLEEP) {
    380           1.1      eeh 			tp->t_state &= ~TS_ASLEEP;
    381           1.1      eeh 			wakeup((caddr_t)cl);
    382           1.1      eeh 		}
    383           1.1      eeh 		selwakeup(&tp->t_wsel);
    384           1.1      eeh 	}
    385           1.1      eeh out:
    386           1.1      eeh 	splx(s);
    387           1.1      eeh }
    388           1.1      eeh 
    389           1.1      eeh /*
    390           1.1      eeh  * Timeout function to do delayed writes to the screen.
    391           1.1      eeh  * Called at splsoftclock when requested by kdstart.
    392           1.1      eeh  */
    393           1.1      eeh static void
    394           1.1      eeh kd_later(tpaddr)
    395           1.1      eeh 	void *tpaddr;
    396           1.1      eeh {
    397           1.1      eeh 	struct tty *tp = tpaddr;
    398           1.1      eeh 	register int s;
    399           1.1      eeh 
    400           1.1      eeh 	kd_putfb(tp);
    401           1.1      eeh 
    402           1.1      eeh 	s = spltty();
    403           1.1      eeh 	tp->t_state &= ~TS_BUSY;
    404           1.1      eeh 	(*linesw[tp->t_line].l_start)(tp);
    405           1.1      eeh 	splx(s);
    406           1.1      eeh }
    407           1.1      eeh 
    408           1.1      eeh /*
    409           1.1      eeh  * Put text on the screen using the PROM monitor.
    410           1.1      eeh  * This can take a while, so to avoid missing
    411           1.1      eeh  * interrupts, this is called at splsoftclock.
    412           1.1      eeh  */
    413           1.1      eeh static void
    414           1.1      eeh kd_putfb(tp)
    415           1.1      eeh 	struct tty *tp;
    416           1.1      eeh {
    417           1.1      eeh 	char buf[PUT_WSIZE];
    418           1.1      eeh 	struct clist *cl = &tp->t_outq;
    419           1.1      eeh 	char *p, *end;
    420           1.1      eeh 	int len;
    421           1.1      eeh 
    422           1.1      eeh 	while ((len = q_to_b(cl, buf, PUT_WSIZE-1)) > 0) {
    423           1.1      eeh 		/* PROM will barf if high bits are set. */
    424           1.1      eeh 		p = buf;
    425           1.1      eeh 		end = buf + len;
    426           1.1      eeh 		while (p < end)
    427           1.1      eeh 			*p++ &= 0x7f;
    428           1.1      eeh 		/* Now let the PROM print it. */
    429           1.1      eeh 		OF_write(OF_stdout(), buf, len);
    430           1.1      eeh 	}
    431           1.1      eeh }
    432           1.1      eeh 
    433           1.1      eeh /*
    434           1.1      eeh  * Our "interrupt" routine for input. This is called by
    435           1.1      eeh  * the keyboard driver (dev/sun/kbd.c) at spltty.
    436           1.1      eeh  */
    437           1.1      eeh void
    438           1.1      eeh kd_input(c)
    439           1.1      eeh 	int c;
    440           1.1      eeh {
    441           1.1      eeh 	struct kd_softc *kd = &kd_softc;
    442           1.1      eeh 	struct tty *tp;
    443           1.1      eeh 
    444           1.1      eeh 	/* XXX: Make sure the device is open. */
    445           1.1      eeh 	tp = kd->kd_tty;
    446           1.1      eeh 	if (tp == NULL)
    447           1.1      eeh 		return;
    448           1.1      eeh 	if ((tp->t_state & TS_ISOPEN) == 0)
    449           1.1      eeh 		return;
    450           1.1      eeh 
    451           1.1      eeh 	(*linesw[tp->t_line].l_rint)(c, tp);
    452           1.1      eeh }
    453           1.1      eeh 
    454           1.1      eeh 
    455           1.1      eeh /****************************************************************
    456           1.1      eeh  * kd console support
    457           1.1      eeh  ****************************************************************/
    458           1.1      eeh 
    459           1.1      eeh /* The debugger gets its own key translation state. */
    460           1.1      eeh static struct kbd_state kdcn_state;
    461           1.1      eeh 
    462           1.1      eeh static void kdcnprobe __P((struct consdev *));
    463           1.1      eeh static void kdcninit __P((struct consdev *));
    464           1.1      eeh static int  kdcngetc __P((dev_t));
    465           1.1      eeh static void kdcnputc __P((dev_t, int));
    466           1.1      eeh static void kdcnpollc __P((dev_t, int));
    467           1.1      eeh 
    468  1.1.1.1.10.1  thorpej /* The keyboard driver uses cn_hw to access the real console driver */
    469  1.1.1.1.10.1  thorpej extern struct consdev consdev_prom;
    470  1.1.1.1.10.1  thorpej struct consdev *cn_hw = &consdev_prom;
    471           1.1      eeh struct consdev consdev_kd = {
    472           1.1      eeh 	kdcnprobe,
    473           1.1      eeh 	kdcninit,
    474           1.1      eeh 	kdcngetc,
    475           1.1      eeh 	kdcnputc,
    476           1.1      eeh 	kdcnpollc,
    477           1.1      eeh };
    478           1.1      eeh 
    479           1.1      eeh /* We never call this. */
    480           1.1      eeh static void
    481           1.1      eeh kdcnprobe(cn)
    482           1.1      eeh 	struct consdev *cn;
    483           1.1      eeh {
    484           1.1      eeh }
    485           1.1      eeh 
    486           1.1      eeh static void
    487           1.1      eeh kdcninit(cn)
    488           1.1      eeh 	struct consdev *cn;
    489           1.1      eeh {
    490           1.1      eeh 	struct kbd_state *ks = &kdcn_state;
    491           1.1      eeh 
    492           1.1      eeh 	cn->cn_dev = makedev(KDMAJOR, 0);
    493           1.1      eeh 	cn->cn_pri = CN_INTERNAL;
    494           1.1      eeh 
    495           1.1      eeh 	/* This prepares kbd_translate() */
    496           1.1      eeh 	ks->kbd_id = KBD_MIN_TYPE;
    497           1.1      eeh 	kbd_xlate_init(ks);
    498           1.1      eeh 
    499           1.1      eeh 	/* Indicate that it is OK to use the PROM fbwrite */
    500           1.1      eeh 	kd_is_console = 1;
    501           1.1      eeh }
    502           1.1      eeh 
    503           1.1      eeh static int
    504           1.1      eeh kdcngetc(dev)
    505           1.1      eeh 	dev_t dev;
    506           1.1      eeh {
    507           1.1      eeh 	struct kbd_state *ks = &kdcn_state;
    508           1.1      eeh 	int code, class, data, keysym;
    509           1.1      eeh 
    510           1.1      eeh 	for (;;) {
    511  1.1.1.1.10.1  thorpej 		code = (*cn_hw->cn_getc)(dev);
    512           1.1      eeh 		keysym = kbd_code_to_keysym(ks, code);
    513           1.1      eeh 		class = KEYSYM_CLASS(keysym);
    514  1.1.1.1.10.1  thorpej 
    515           1.1      eeh 		switch (class) {
    516           1.1      eeh 		case KEYSYM_ASCII:
    517           1.1      eeh 			goto out;
    518  1.1.1.1.10.1  thorpej 
    519           1.1      eeh 		case KEYSYM_CLRMOD:
    520           1.1      eeh 		case KEYSYM_SETMOD:
    521           1.1      eeh 			data = (keysym & 0x1F);
    522           1.1      eeh 			/* Only allow ctrl or shift. */
    523           1.1      eeh 			if (data > KBMOD_SHIFT_R)
    524           1.1      eeh 				break;
    525           1.1      eeh 			data = 1 << data;
    526           1.1      eeh 			if (class == KEYSYM_SETMOD)
    527           1.1      eeh 				ks->kbd_modbits |= data;
    528           1.1      eeh 			else
    529           1.1      eeh 				ks->kbd_modbits &= ~data;
    530           1.1      eeh 			break;
    531  1.1.1.1.10.1  thorpej 
    532           1.1      eeh 		case KEYSYM_ALL_UP:
    533           1.1      eeh 			/* No toggle keys here. */
    534           1.1      eeh 			ks->kbd_modbits = 0;
    535           1.1      eeh 			break;
    536  1.1.1.1.10.1  thorpej 
    537           1.1      eeh 		default:	/* ignore all other keysyms */
    538           1.1      eeh 			break;
    539           1.1      eeh 		}
    540           1.1      eeh 	}
    541           1.1      eeh out:
    542           1.1      eeh 	return (keysym);
    543           1.1      eeh }
    544           1.1      eeh 
    545           1.1      eeh static void
    546           1.1      eeh kdcnputc(dev, c)
    547           1.1      eeh 	dev_t dev;
    548           1.1      eeh 	int c;
    549           1.1      eeh {
    550  1.1.1.1.10.1  thorpej 	int s;
    551           1.1      eeh 	char c0 = (c & 0x7f);
    552           1.1      eeh 
    553  1.1.1.1.10.1  thorpej 	s = splhigh();
    554  1.1.1.1.10.1  thorpej 	OF_write(OF_stdout(), &c0, 1);
    555  1.1.1.1.10.1  thorpej 	splx(s);
    556           1.1      eeh }
    557           1.1      eeh 
    558           1.1      eeh static void
    559           1.1      eeh kdcnpollc(dev, on)
    560           1.1      eeh 	dev_t dev;
    561           1.1      eeh 	int on;
    562           1.1      eeh {
    563           1.1      eeh 	struct kbd_state *ks = &kdcn_state;
    564           1.1      eeh 
    565           1.1      eeh 	if (on) {
    566           1.1      eeh 		/* Entering debugger. */
    567           1.1      eeh #if NFB > 0
    568           1.1      eeh 		fb_unblank();
    569           1.1      eeh #endif
    570           1.1      eeh 		/* Clear shift keys too. */
    571           1.1      eeh 		ks->kbd_modbits = 0;
    572           1.1      eeh 	} else {
    573           1.1      eeh 		/* Resuming kernel. */
    574           1.1      eeh 	}
    575  1.1.1.1.10.1  thorpej 	(*cn_hw->cn_pollc)(dev, on);
    576           1.1      eeh }
    577           1.1      eeh 
    578