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