147986Sdonn /*
247986Sdonn * Copyright (c) 1988 University of Utah.
3*63356Sbostic * Copyright (c) 1991, 1993
4*63356Sbostic * The Regents of the University of California. All rights reserved.
547986Sdonn *
647986Sdonn * This code is derived from software contributed to Berkeley by
747986Sdonn * the Systems Programming Group of the University of Utah Computer
847986Sdonn * Science Department.
947986Sdonn *
1049527Sdonn * %sccs.include.redist.c%
1147986Sdonn *
12*63356Sbostic * @(#)cons.c 8.1 (Berkeley) 06/11/93
1347986Sdonn */
1447986Sdonn
1549527Sdonn
1656511Sbostic #include <sys/param.h>
1756511Sbostic #include <sys/proc.h>
1856511Sbostic #include <sys/user.h>
1956511Sbostic #include <sys/systm.h>
2056511Sbostic #include <sys/buf.h>
2156511Sbostic #include <sys/ioctl.h>
2256511Sbostic #include <sys/tty.h>
2356511Sbostic #include <sys/file.h>
2456511Sbostic #include <sys/conf.h>
2547986Sdonn
2656511Sbostic #include <i386/i386/cons.h>
2747986Sdonn
2847986Sdonn /* XXX - all this could be autoconfig()ed */
2949527Sdonn int pccnprobe(), pccninit(), pccngetc(), pccnputc();
3049527Sdonn #include "com.h"
3149527Sdonn #if NCOM > 0
3249527Sdonn int comcnprobe(), comcninit(), comcngetc(), comcnputc();
3347986Sdonn #endif
3447986Sdonn
3547986Sdonn struct consdev constab[] = {
3649527Sdonn { pccnprobe, pccninit, pccngetc, pccnputc },
3749527Sdonn #if NCOM > 0
3849527Sdonn { comcnprobe, comcninit, comcngetc, comcnputc },
3947986Sdonn #endif
4047986Sdonn { 0 },
4147986Sdonn };
4247986Sdonn /* end XXX */
4347986Sdonn
4447986Sdonn struct tty *constty = 0; /* virtual console output device */
4547986Sdonn struct consdev *cn_tab; /* physical console device info */
4647986Sdonn struct tty *cn_tty; /* XXX: console tty struct for tprintf */
4747986Sdonn
cninit()4847986Sdonn cninit()
4947986Sdonn {
5047986Sdonn register struct consdev *cp;
5147986Sdonn
5247986Sdonn /*
5347986Sdonn * Collect information about all possible consoles
5447986Sdonn * and find the one with highest priority
5547986Sdonn */
5647986Sdonn for (cp = constab; cp->cn_probe; cp++) {
5747986Sdonn (*cp->cn_probe)(cp);
5847986Sdonn if (cp->cn_pri > CN_DEAD &&
5947986Sdonn (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
6047986Sdonn cn_tab = cp;
6147986Sdonn }
6247986Sdonn /*
6347986Sdonn * No console, we can handle it
6447986Sdonn */
6547986Sdonn if ((cp = cn_tab) == NULL)
6647986Sdonn return;
6747986Sdonn /*
6847986Sdonn * Turn on console
6947986Sdonn */
7047986Sdonn cn_tty = cp->cn_tp;
7147986Sdonn (*cp->cn_init)(cp);
7247986Sdonn }
7347986Sdonn
cnopen(dev,flag,mode,p)7449527Sdonn cnopen(dev, flag, mode, p)
7547986Sdonn dev_t dev;
7649527Sdonn int flag, mode;
7749527Sdonn struct proc *p;
7847986Sdonn {
7947986Sdonn if (cn_tab == NULL)
8049527Sdonn return (0);
8147986Sdonn dev = cn_tab->cn_dev;
8249527Sdonn return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p));
8347986Sdonn }
8447986Sdonn
cnclose(dev,flag,mode,p)8549527Sdonn cnclose(dev, flag, mode, p)
8647986Sdonn dev_t dev;
8749527Sdonn int flag, mode;
8849527Sdonn struct proc *p;
8947986Sdonn {
9047986Sdonn if (cn_tab == NULL)
9149527Sdonn return (0);
9247986Sdonn dev = cn_tab->cn_dev;
9349527Sdonn return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p));
9447986Sdonn }
9547986Sdonn
cnread(dev,uio,flag)9647986Sdonn cnread(dev, uio, flag)
9747986Sdonn dev_t dev;
9847986Sdonn struct uio *uio;
9947986Sdonn {
10047986Sdonn if (cn_tab == NULL)
10149527Sdonn return (0);
10247986Sdonn dev = cn_tab->cn_dev;
10347986Sdonn return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
10447986Sdonn }
10547986Sdonn
cnwrite(dev,uio,flag)10647986Sdonn cnwrite(dev, uio, flag)
10747986Sdonn dev_t dev;
10847986Sdonn struct uio *uio;
10947986Sdonn {
11047986Sdonn if (cn_tab == NULL)
11149527Sdonn return (0);
11247986Sdonn dev = cn_tab->cn_dev;
11347986Sdonn return ((*cdevsw[major(dev)].d_write)(dev, uio, flag));
11447986Sdonn }
11547986Sdonn
cnioctl(dev,cmd,data,flag,p)11649527Sdonn cnioctl(dev, cmd, data, flag, p)
11747986Sdonn dev_t dev;
11847986Sdonn caddr_t data;
11949527Sdonn struct proc *p;
12047986Sdonn {
12147986Sdonn int error;
12247986Sdonn
12347986Sdonn if (cn_tab == NULL)
12449527Sdonn return (0);
12547986Sdonn /*
12647986Sdonn * Superuser can always use this to wrest control of console
12747986Sdonn * output from the "virtual" console.
12847986Sdonn */
12947986Sdonn if (cmd == TIOCCONS && constty) {
13049527Sdonn error = suser(p->p_ucred, (u_short *) NULL);
13147986Sdonn if (error)
13247986Sdonn return (error);
13347986Sdonn constty = NULL;
13447986Sdonn return (0);
13547986Sdonn }
13647986Sdonn dev = cn_tab->cn_dev;
13749527Sdonn return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
13847986Sdonn }
13947986Sdonn
14047986Sdonn /*ARGSUSED*/
cnselect(dev,rw,p)14149527Sdonn cnselect(dev, rw, p)
14247986Sdonn dev_t dev;
14347986Sdonn int rw;
14449527Sdonn struct proc *p;
14547986Sdonn {
14647986Sdonn if (cn_tab == NULL)
14749527Sdonn return (1);
14849527Sdonn return (ttselect(cn_tab->cn_dev, rw, p));
14947986Sdonn }
15047986Sdonn
cngetc()15147986Sdonn cngetc()
15247986Sdonn {
15347986Sdonn if (cn_tab == NULL)
15449527Sdonn return (0);
15549527Sdonn return ((*cn_tab->cn_getc)(cn_tab->cn_dev));
15647986Sdonn }
15747986Sdonn
cnputc(c)15847986Sdonn cnputc(c)
15947986Sdonn register int c;
16047986Sdonn {
16147986Sdonn if (cn_tab == NULL)
16247986Sdonn return;
16347986Sdonn if (c) {
16447986Sdonn (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
16547986Sdonn if (c == '\n')
16647986Sdonn (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
16747986Sdonn }
16847986Sdonn }
169