1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1992 OMRON Corporation. 4 * Copyright (c) 1990, 1992 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the Systems Programming Group of the University of Utah Computer 9 * Science Department. 10 * 11 * %sccs.include.redist.c% 12 * 13 * from: Utah $Hdr: cons.c 1.1 90/07/09$ 14 * 15 * from: hp300/hp300/cons.c 7.1 (Berkeley) 6/4/92 16 * 17 * @(#)cons.c 7.1 (Berkeley) 06/15/92 18 */ 19 20 #include "sys/param.h" 21 #include "sys/proc.h" 22 #include "sys/systm.h" 23 #include "sys/buf.h" 24 #include "sys/ioctl.h" 25 #include "sys/tty.h" 26 #include "sys/file.h" 27 #include "sys/conf.h" 28 29 #include "cons.h" 30 31 /* XXX - all this could be autoconfig()ed */ 32 #include "sio.h" 33 #if NSIO > 0 34 int siocnprobe(), siocninit(), siocngetc(), siocnputc(); 35 #endif 36 37 struct consdev constab[] = { 38 #if NSIO > 0 39 { siocnprobe, siocninit, siocngetc, siocnputc }, 40 #endif 41 { 0 }, 42 }; 43 /* end XXX */ 44 45 struct tty *constty = 0; /* virtual console output device */ 46 struct consdev *cn_tab; /* physical console device info */ 47 struct tty *cn_tty; /* XXX: console tty struct for tprintf */ 48 49 cninit() 50 { 51 register struct consdev *cp; 52 53 /* 54 * Collect information about all possible consoles 55 * and find the one with highest priority 56 */ 57 for (cp = constab; cp->cn_probe; cp++) { 58 (*cp->cn_probe)(cp); 59 if (cp->cn_pri > CN_DEAD && 60 (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri)) 61 cn_tab = cp; 62 } 63 /* 64 * No console, we can handle it 65 */ 66 if ((cp = cn_tab) == NULL) 67 return; 68 /* 69 * Turn on console 70 */ 71 cn_tty = cp->cn_tp; 72 (*cp->cn_init)(cp); 73 } 74 75 cnopen(dev, flag, mode, p) 76 dev_t dev; 77 int flag, mode; 78 struct proc *p; 79 { 80 if (cn_tab == NULL) 81 return (0); 82 dev = cn_tab->cn_dev; 83 return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p)); 84 } 85 86 cnclose(dev, flag, mode, p) 87 dev_t dev; 88 int flag, mode; 89 struct proc *p; 90 { 91 if (cn_tab == NULL) 92 return (0); 93 dev = cn_tab->cn_dev; 94 return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p)); 95 } 96 97 cnread(dev, uio, flag) 98 dev_t dev; 99 struct uio *uio; 100 { 101 if (cn_tab == NULL) 102 return (0); 103 dev = cn_tab->cn_dev; 104 return ((*cdevsw[major(dev)].d_read)(dev, uio, flag)); 105 } 106 107 cnwrite(dev, uio, flag) 108 dev_t dev; 109 struct uio *uio; 110 { 111 if (cn_tab == NULL) 112 return (0); 113 dev = cn_tab->cn_dev; 114 return ((*cdevsw[major(dev)].d_write)(dev, uio, flag)); 115 } 116 117 cnioctl(dev, cmd, data, flag, p) 118 dev_t dev; 119 caddr_t data; 120 struct proc *p; 121 { 122 int error; 123 124 if (cn_tab == NULL) 125 return (0); 126 /* 127 * Superuser can always use this to wrest control of console 128 * output from the "virtual" console. 129 */ 130 if (cmd == TIOCCONS && constty) { 131 error = suser(p->p_ucred, (u_short *) NULL); 132 if (error) 133 return (error); 134 constty = NULL; 135 return (0); 136 } 137 dev = cn_tab->cn_dev; 138 return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p)); 139 } 140 141 /*ARGSUSED*/ 142 cnselect(dev, rw, p) 143 dev_t dev; 144 int rw; 145 struct proc *p; 146 { 147 if (cn_tab == NULL) 148 return (1); 149 return (ttselect(cn_tab->cn_dev, rw, p)); 150 } 151 152 cngetc() 153 { 154 if (cn_tab == NULL) 155 return (0); 156 return ((*cn_tab->cn_getc)(cn_tab->cn_dev)); 157 } 158 159 cnputc(c) 160 register int c; 161 { 162 if (cn_tab == NULL) 163 return; 164 if (c) { 165 (*cn_tab->cn_putc)(cn_tab->cn_dev, c); 166 if (c == '\n') 167 (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r'); 168 } 169 } 170