Home | History | Annotate | Line # | Download | only in dev
kd.c revision 1.10
      1  1.10  gwr /*	$NetBSD: kd.c,v 1.10 1995/03/24 19:48:44 gwr Exp $	*/
      2   1.4  cgd 
      3   1.1  gwr /*
      4   1.1  gwr  * Copyright (c) 1994 Gordon W. Ross
      5   1.1  gwr  * All rights reserved.
      6   1.1  gwr  *
      7   1.1  gwr  * Redistribution and use in source and binary forms, with or without
      8   1.1  gwr  * modification, are permitted provided that the following conditions
      9   1.1  gwr  * are met:
     10   1.1  gwr  * 1. Redistributions of source code must retain the above copyright
     11   1.1  gwr  *    notice, this list of conditions and the following disclaimer.
     12   1.1  gwr  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1  gwr  *    notice, this list of conditions and the following disclaimer in the
     14   1.1  gwr  *    documentation and/or other materials provided with the distribution.
     15   1.2  gwr  * 3. The name of the author may not be used to endorse or promote products
     16   1.1  gwr  *    derived from this software without specific prior written permission.
     17   1.1  gwr  *
     18   1.2  gwr  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19   1.2  gwr  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20   1.2  gwr  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21   1.2  gwr  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22   1.2  gwr  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23   1.2  gwr  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24   1.2  gwr  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25   1.2  gwr  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26   1.2  gwr  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27   1.2  gwr  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28   1.1  gwr  */
     29   1.1  gwr 
     30   1.1  gwr /*
     31   1.1  gwr  * Keyboard/Display device.
     32   1.1  gwr  *
     33   1.1  gwr  * This driver exists simply to provide a tty device that
     34   1.1  gwr  * the indirect console driver can point to.
     35   1.1  gwr  * The kbd driver sends its input here.
     36   1.1  gwr  * Output goes to the screen via PROM printf.
     37   1.1  gwr  */
     38   1.1  gwr 
     39   1.1  gwr #include <sys/param.h>
     40   1.1  gwr #include <sys/proc.h>
     41   1.1  gwr #include <sys/systm.h>
     42   1.1  gwr #include <sys/ioctl.h>
     43   1.1  gwr #include <sys/tty.h>
     44   1.1  gwr #include <sys/file.h>
     45   1.1  gwr #include <sys/conf.h>
     46   1.1  gwr #include <sys/device.h>
     47   1.1  gwr 
     48   1.1  gwr #include <machine/autoconf.h>
     49   1.1  gwr #include <machine/mon.h>
     50   1.1  gwr 
     51   1.1  gwr #include <dev/cons.h>
     52   1.1  gwr 
     53   1.1  gwr #define BURST	64
     54   1.1  gwr 
     55   1.1  gwr struct tty *kd_tty[1];
     56   1.1  gwr 
     57   1.1  gwr int kdopen(dev_t, int, int, struct proc *);
     58   1.1  gwr int kdclose(dev_t, int, int, struct proc *);
     59   1.1  gwr int kdread(dev_t, struct uio *, int);
     60   1.1  gwr int kdwrite(dev_t, struct uio *, int);
     61   1.1  gwr int kdioctl(dev_t, int, caddr_t, int, struct proc *);
     62   1.1  gwr 
     63   1.1  gwr static int kdparam(struct tty *, struct termios *);
     64   1.1  gwr static void kdstart(struct tty *);
     65   1.1  gwr 
     66  1.10  gwr int kd_is_console;
     67  1.10  gwr 
     68   1.7  gwr /* This is called by kbd_serial() like a pseudo-device. */
     69   1.7  gwr void
     70   1.7  gwr kd_attach(n)
     71   1.7  gwr 	int n;
     72   1.1  gwr {
     73   1.1  gwr 	kd_tty[0] = ttymalloc();
     74   1.1  gwr 
     75   1.1  gwr 	/* Tell keyboard module where to send read data. */
     76   1.1  gwr 	kbd_ascii(kd_tty[0]);
     77   1.1  gwr }
     78   1.1  gwr 
     79   1.1  gwr int
     80   1.1  gwr kdopen(dev, flag, mode, p)
     81   1.1  gwr 	dev_t dev;
     82   1.1  gwr 	int flag, mode;
     83   1.1  gwr 	struct proc *p;
     84   1.1  gwr {
     85   1.3  gwr 	int error, unit;
     86   1.1  gwr 	struct tty *tp;
     87   1.1  gwr 
     88   1.1  gwr 	unit = minor(dev);
     89   1.1  gwr 	if (unit) return ENXIO;
     90   1.1  gwr 
     91   1.1  gwr 	tp = kd_tty[unit];
     92   1.1  gwr 	if (tp == NULL)
     93   1.1  gwr 		return ENXIO;
     94   1.3  gwr 
     95   1.8  gwr 	if ((error = kbd_iopen()) != 0) {
     96   1.8  gwr #ifdef	DIAGNOSTIC
     97   1.8  gwr 		printf("kd: kbd_iopen, error=%d\n", error);
     98   1.8  gwr #endif
     99   1.3  gwr 		return (error);
    100   1.8  gwr 	}
    101   1.1  gwr 
    102   1.1  gwr 	tp->t_oproc = kdstart;
    103   1.1  gwr 	tp->t_param = kdparam;
    104   1.1  gwr 	tp->t_dev = dev;
    105   1.1  gwr 	if ((tp->t_state & TS_ISOPEN) == 0) {
    106   1.1  gwr 		tp->t_state |= TS_WOPEN;
    107   1.1  gwr 		ttychars(tp);
    108   1.1  gwr 		tp->t_iflag = TTYDEF_IFLAG;
    109   1.1  gwr 		tp->t_oflag = TTYDEF_OFLAG;
    110   1.1  gwr 		tp->t_cflag = TTYDEF_CFLAG;
    111   1.1  gwr 		tp->t_lflag = TTYDEF_LFLAG;
    112   1.1  gwr 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
    113   1.1  gwr 		kdparam(tp, &tp->t_termios);
    114   1.1  gwr 		ttsetwater(tp);
    115   1.1  gwr 	} else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
    116   1.1  gwr 		return EBUSY;
    117   1.1  gwr 	tp->t_state |= TS_CARR_ON;
    118   1.1  gwr 
    119   1.1  gwr 	return ((*linesw[tp->t_line].l_open)(dev, tp));
    120   1.1  gwr }
    121   1.1  gwr 
    122   1.1  gwr int
    123   1.1  gwr kdclose(dev, flag, mode, p)
    124   1.1  gwr 	dev_t dev;
    125   1.1  gwr 	int flag, mode;
    126   1.1  gwr 	struct proc *p;
    127   1.1  gwr {
    128   1.1  gwr 	int unit = minor(dev);
    129   1.1  gwr 	struct tty *tp = kd_tty[unit];
    130   1.1  gwr 
    131   1.1  gwr 	(*linesw[tp->t_line].l_close)(tp, flag);
    132   1.1  gwr 	ttyclose(tp);
    133   1.1  gwr 	return (0);
    134   1.1  gwr }
    135   1.1  gwr 
    136   1.1  gwr int
    137   1.1  gwr kdread(dev, uio, flag)
    138   1.1  gwr 	dev_t dev;
    139   1.1  gwr 	struct uio *uio;
    140   1.1  gwr 	int flag;
    141   1.1  gwr {
    142   1.1  gwr 	int unit = minor(dev);
    143   1.1  gwr 	struct tty *tp = kd_tty[unit];
    144   1.1  gwr 
    145   1.1  gwr 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
    146   1.1  gwr }
    147   1.1  gwr 
    148   1.1  gwr int
    149   1.1  gwr kdwrite(dev, uio, flag)
    150   1.1  gwr 	dev_t dev;
    151   1.1  gwr 	struct uio *uio;
    152   1.1  gwr 	int flag;
    153   1.1  gwr {
    154   1.1  gwr 	int unit = minor(dev);
    155   1.1  gwr 	struct tty *tp = kd_tty[unit];
    156   1.1  gwr 
    157   1.1  gwr 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
    158   1.1  gwr }
    159   1.1  gwr 
    160   1.1  gwr int
    161   1.1  gwr kdioctl(dev, cmd, data, flag, p)
    162   1.1  gwr 	dev_t dev;
    163   1.1  gwr 	int cmd;
    164   1.1  gwr 	caddr_t data;
    165   1.1  gwr 	int flag;
    166   1.1  gwr 	struct proc *p;
    167   1.1  gwr {
    168   1.1  gwr 	int error;
    169   1.1  gwr 	int unit = minor(dev);
    170   1.1  gwr 	struct tty *tp = kd_tty[unit];
    171   1.1  gwr 
    172   1.1  gwr 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
    173   1.1  gwr 	if (error >= 0)
    174   1.1  gwr 		return error;
    175   1.1  gwr 	error = ttioctl(tp, cmd, data, flag, p);
    176   1.1  gwr 	if (error >= 0)
    177   1.1  gwr 		return error;
    178   1.1  gwr 
    179   1.1  gwr 	/* Handle any ioctl commands specific to kbd/display. */
    180   1.1  gwr 	/* XXX - Send KB* ioctls to kbd module? */
    181   1.1  gwr 	/* XXX - Send FB* ioctls to fb module?  */
    182   1.1  gwr 
    183   1.1  gwr 	return ENOTTY;
    184   1.1  gwr }
    185   1.1  gwr 
    186   1.1  gwr void
    187   1.1  gwr kdstart(tp)
    188   1.1  gwr 	struct tty *tp;
    189   1.1  gwr {
    190   1.1  gwr 	struct clist *cl;
    191   1.1  gwr 	int s, len;
    192   1.1  gwr 	u_char buf[BURST];
    193   1.1  gwr 
    194   1.1  gwr 	s = spltty();
    195   1.1  gwr 	if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT))
    196   1.1  gwr 		goto out;
    197   1.1  gwr 	tp->t_state |= TS_BUSY;
    198   1.1  gwr 	cl = &tp->t_outq;
    199   1.1  gwr 
    200   1.1  gwr 	/*
    201   1.1  gwr 	 * XXX - It might be nice to have our own fbputs() so
    202   1.1  gwr 	 * we would not have to use the (slow) PROM printf.
    203   1.1  gwr 	 */
    204   1.1  gwr 	while ((len = q_to_b(cl, buf, BURST-1)) > 0) {
    205   1.1  gwr 		buf[len] = '\0';
    206  1.10  gwr 
    207  1.10  gwr 		/*
    208  1.10  gwr 		 * Note that this device might NOT be the console.
    209  1.10  gwr 		 * Using the PROM to put text on the screen is easy,
    210  1.10  gwr 		 * but it only works if this is the console (sigh).
    211  1.10  gwr 		 * If this is not the console, you are typing blind!
    212  1.10  gwr 		 */
    213  1.10  gwr 		if (kd_is_console) {
    214  1.10  gwr 			(romVectorPtr->fbWriteStr)(buf, len);
    215  1.10  gwr 		}
    216   1.1  gwr 	}
    217   1.1  gwr 
    218   1.1  gwr 	tp->t_state &= ~TS_BUSY;
    219   1.1  gwr 	if (tp->t_state & TS_ASLEEP) {
    220   1.1  gwr 		tp->t_state &= ~TS_ASLEEP;
    221   1.1  gwr 		wakeup((caddr_t)cl);
    222   1.1  gwr 	}
    223   1.1  gwr 	selwakeup(&tp->t_wsel);
    224   1.1  gwr out:
    225   1.1  gwr 	splx(s);
    226   1.1  gwr }
    227   1.1  gwr 
    228   1.1  gwr static int
    229   1.1  gwr kdparam(tp, t)
    230   1.1  gwr 	struct tty *tp;
    231   1.1  gwr 	struct termios *t;
    232   1.1  gwr {
    233   1.1  gwr 	/* XXX - These are ignored... */
    234   1.1  gwr 	tp->t_ispeed = t->c_ispeed;
    235   1.1  gwr 	tp->t_ospeed = t->c_ospeed;
    236   1.1  gwr 	tp->t_cflag = t->c_cflag;
    237   1.1  gwr 	return 0;
    238   1.1  gwr }
    239   1.1  gwr 
    240   1.1  gwr 
    241   1.1  gwr /*
    242   1.1  gwr  * kd console support
    243   1.1  gwr  */
    244   1.1  gwr 
    245   1.8  gwr extern int zscnprobe_kbd(), zscngetc(), kbd_translate();
    246   1.1  gwr 
    247   1.1  gwr kdcnprobe(cp)
    248   1.1  gwr 	struct consdev *cp;
    249   1.1  gwr {
    250   1.1  gwr 	int maj;
    251   1.1  gwr 
    252   1.1  gwr 	/* locate the major number */
    253   1.1  gwr 	for (maj = 0; maj < nchrdev; maj++)
    254   1.6  gwr 		if (cdevsw[maj].d_open == (void*)kdopen)
    255   1.1  gwr 			break;
    256   1.1  gwr 
    257   1.1  gwr 	/* initialize required fields */
    258   1.1  gwr 	cp->cn_dev = makedev(maj, 0);
    259   1.1  gwr 	cp->cn_pri = zscnprobe_kbd();
    260   1.1  gwr }
    261   1.1  gwr 
    262   1.1  gwr kdcninit(cp)
    263   1.1  gwr 	struct consdev *cp;
    264   1.1  gwr {
    265   1.8  gwr 
    266   1.8  gwr 	/* This prepares zscngetc() */
    267   1.8  gwr 	zs_set_conschan(1, 0);
    268   1.8  gwr 
    269   1.8  gwr 	/* This prepares kbd_translate() */
    270   1.8  gwr 	kbd_init_tables();
    271  1.10  gwr 
    272  1.10  gwr 	/* Indicate that it is OK to use the PROM fbwrite */
    273  1.10  gwr 	kd_is_console = 1;
    274   1.8  gwr 
    275   1.1  gwr 	mon_printf("console on kd0 (keyboard/display)\n");
    276   1.1  gwr }
    277   1.1  gwr 
    278   1.1  gwr kdcngetc(dev)
    279   1.1  gwr 	dev_t dev;
    280   1.1  gwr {
    281   1.8  gwr 	int c;
    282   1.1  gwr 
    283   1.8  gwr 	do {
    284   1.8  gwr 		c = zscngetc(0);
    285   1.8  gwr 		c = kbd_translate(c);
    286   1.8  gwr 	} while (c == -1);
    287   1.1  gwr 
    288   1.1  gwr 	return (c);
    289   1.1  gwr }
    290   1.1  gwr 
    291   1.1  gwr kdcnputc(dev, c)
    292   1.1  gwr 	dev_t dev;
    293   1.1  gwr 	int c;
    294   1.1  gwr {
    295   1.1  gwr 	int s;
    296   1.1  gwr 
    297   1.1  gwr 	s = splhigh();
    298   1.1  gwr #if 0
    299   1.1  gwr 	/* XXX - Is this worth doing? */
    300   1.1  gwr 	(romVectorPtr->fbWriteChar)(c);
    301   1.1  gwr #else
    302   1.1  gwr 	mon_putchar(c);
    303   1.1  gwr #endif
    304   1.1  gwr 	splx(s);
    305   1.9  gwr }
    306   1.9  gwr 
    307   1.9  gwr extern void fb_unblank();
    308   1.9  gwr void kdcnpollc(dev, on)
    309   1.9  gwr 	dev_t dev;
    310   1.9  gwr 	int on;
    311   1.9  gwr {
    312   1.9  gwr 	if (on)
    313   1.9  gwr 		fb_unblank();
    314   1.1  gwr }
    315