147986Sdonn /* 247986Sdonn * Copyright (c) 1988 University of Utah. 349527Sdonn * Copyright (c) 1991 The Regents of the University of California. 447986Sdonn * 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*56511Sbostic * @(#)cons.c 7.3 (Berkeley) 10/11/92 1347986Sdonn */ 1447986Sdonn 1549527Sdonn 16*56511Sbostic #include <sys/param.h> 17*56511Sbostic #include <sys/proc.h> 18*56511Sbostic #include <sys/user.h> 19*56511Sbostic #include <sys/systm.h> 20*56511Sbostic #include <sys/buf.h> 21*56511Sbostic #include <sys/ioctl.h> 22*56511Sbostic #include <sys/tty.h> 23*56511Sbostic #include <sys/file.h> 24*56511Sbostic #include <sys/conf.h> 2547986Sdonn 26*56511Sbostic #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 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 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 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 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 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 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*/ 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 15147986Sdonn cngetc() 15247986Sdonn { 15347986Sdonn if (cn_tab == NULL) 15449527Sdonn return (0); 15549527Sdonn return ((*cn_tab->cn_getc)(cn_tab->cn_dev)); 15647986Sdonn } 15747986Sdonn 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