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