1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1991, 1993 4 * The Regents of the University of California. 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 * @(#)cons.c 8.1 (Berkeley) 06/11/93 13 */ 14 15 16 #include <sys/param.h> 17 #include <sys/proc.h> 18 #include <sys/user.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 <i386/i386/cons.h> 27 28 /* XXX - all this could be autoconfig()ed */ 29 int pccnprobe(), pccninit(), pccngetc(), pccnputc(); 30 #include "com.h" 31 #if NCOM > 0 32 int comcnprobe(), comcninit(), comcngetc(), comcnputc(); 33 #endif 34 35 struct consdev constab[] = { 36 { pccnprobe, pccninit, pccngetc, pccnputc }, 37 #if NCOM > 0 38 { comcnprobe, comcninit, comcngetc, comcnputc }, 39 #endif 40 { 0 }, 41 }; 42 /* end XXX */ 43 44 struct tty *constty = 0; /* virtual console output device */ 45 struct consdev *cn_tab; /* physical console device info */ 46 struct tty *cn_tty; /* XXX: console tty struct for tprintf */ 47 48 cninit() 49 { 50 register struct consdev *cp; 51 52 /* 53 * Collect information about all possible consoles 54 * and find the one with highest priority 55 */ 56 for (cp = constab; cp->cn_probe; cp++) { 57 (*cp->cn_probe)(cp); 58 if (cp->cn_pri > CN_DEAD && 59 (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri)) 60 cn_tab = cp; 61 } 62 /* 63 * No console, we can handle it 64 */ 65 if ((cp = cn_tab) == NULL) 66 return; 67 /* 68 * Turn on console 69 */ 70 cn_tty = cp->cn_tp; 71 (*cp->cn_init)(cp); 72 } 73 74 cnopen(dev, flag, mode, p) 75 dev_t dev; 76 int flag, mode; 77 struct proc *p; 78 { 79 if (cn_tab == NULL) 80 return (0); 81 dev = cn_tab->cn_dev; 82 return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p)); 83 } 84 85 cnclose(dev, flag, mode, p) 86 dev_t dev; 87 int flag, mode; 88 struct proc *p; 89 { 90 if (cn_tab == NULL) 91 return (0); 92 dev = cn_tab->cn_dev; 93 return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p)); 94 } 95 96 cnread(dev, uio, flag) 97 dev_t dev; 98 struct uio *uio; 99 { 100 if (cn_tab == NULL) 101 return (0); 102 dev = cn_tab->cn_dev; 103 return ((*cdevsw[major(dev)].d_read)(dev, uio, flag)); 104 } 105 106 cnwrite(dev, uio, flag) 107 dev_t dev; 108 struct uio *uio; 109 { 110 if (cn_tab == NULL) 111 return (0); 112 dev = cn_tab->cn_dev; 113 return ((*cdevsw[major(dev)].d_write)(dev, uio, flag)); 114 } 115 116 cnioctl(dev, cmd, data, flag, p) 117 dev_t dev; 118 caddr_t data; 119 struct proc *p; 120 { 121 int error; 122 123 if (cn_tab == NULL) 124 return (0); 125 /* 126 * Superuser can always use this to wrest control of console 127 * output from the "virtual" console. 128 */ 129 if (cmd == TIOCCONS && constty) { 130 error = suser(p->p_ucred, (u_short *) NULL); 131 if (error) 132 return (error); 133 constty = NULL; 134 return (0); 135 } 136 dev = cn_tab->cn_dev; 137 return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p)); 138 } 139 140 /*ARGSUSED*/ 141 cnselect(dev, rw, p) 142 dev_t dev; 143 int rw; 144 struct proc *p; 145 { 146 if (cn_tab == NULL) 147 return (1); 148 return (ttselect(cn_tab->cn_dev, rw, p)); 149 } 150 151 cngetc() 152 { 153 if (cn_tab == NULL) 154 return (0); 155 return ((*cn_tab->cn_getc)(cn_tab->cn_dev)); 156 } 157 158 cnputc(c) 159 register int c; 160 { 161 if (cn_tab == NULL) 162 return; 163 if (c) { 164 (*cn_tab->cn_putc)(cn_tab->cn_dev, c); 165 if (c == '\n') 166 (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r'); 167 } 168 } 169