|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988-1994, The University of Utah and ! 3: * the Computer Systems Laboratory (CSL). All rights reserved. ! 4: * ! 5: * Permission to use, copy, modify and distribute this software is hereby ! 6: * granted provided that (1) source code retains these copyright, permission, ! 7: * and disclaimer notices, and (2) redistributions including binaries ! 8: * reproduce the notices in supporting documentation, and (3) all advertising ! 9: * materials mentioning features or use of this software display the following ! 10: * acknowledgement: ``This product includes software developed by the ! 11: * Computer Systems Laboratory at the University of Utah.'' ! 12: * ! 13: * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS ! 14: * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF ! 15: * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 16: * ! 17: * CSL requests users of this software to return to [email protected] any ! 18: * improvements that they make and grant CSL redistribution rights. ! 19: * ! 20: * Utah $Hdr: cons.c 1.14 94/12/14$ ! 21: */ ! 22: ! 23: #ifdef MACH_KERNEL ! 24: #include <sys/types.h> ! 25: #include <device/conf.h> ! 26: #include <mach/boolean.h> ! 27: #include <cons.h> ! 28: #else ! 29: #include <sys/param.h> ! 30: #include <sys/user.h> ! 31: #include <sys/systm.h> ! 32: #include <sys/buf.h> ! 33: #include <sys/ioctl.h> ! 34: #include <sys/tty.h> ! 35: #include <sys/file.h> ! 36: #include <sys/conf.h> ! 37: #include <hpdev/cons.h> ! 38: #endif ! 39: ! 40: static int cn_inited = 0; ! 41: static struct consdev *cn_tab = 0; /* physical console device info */ ! 42: #ifndef MACH_KERNEL ! 43: static struct tty *constty = 0; /* virtual console output device */ ! 44: #endif ! 45: ! 46: /* ! 47: * ROM getc/putc primitives. ! 48: * On some architectures, the boot ROM provides basic character input/output ! 49: * routines that can be used before devices are configured or virtual memory ! 50: * is enabled. This can be useful to debug (or catch panics from) code early ! 51: * in the bootstrap procedure. ! 52: */ ! 53: int (*romgetc)() = 0; ! 54: void (*romputc)() = 0; ! 55: ! 56: #if CONSBUFSIZE > 0 ! 57: /* ! 58: * Temporary buffer to store console output before a console is selected. ! 59: * This is statically allocated so it can be called before malloc/kmem_alloc ! 60: * have been initialized. It is initialized so it won't be clobbered as ! 61: * part of the zeroing of BSS (on PA/Mach). ! 62: */ ! 63: static char consbuf[CONSBUFSIZE] = { 0 }; ! 64: static char *consbp = consbuf; ! 65: static int consbufused = 0; ! 66: #endif ! 67: ! 68: cninit() ! 69: { ! 70: struct consdev *cp; ! 71: #ifdef MACH_KERNEL ! 72: dev_ops_t cn_ops; ! 73: int x; ! 74: #endif ! 75: ! 76: if (cn_inited) ! 77: return; ! 78: ! 79: /* ! 80: * Collect information about all possible consoles ! 81: * and find the one with highest priority ! 82: */ ! 83: for (cp = constab; cp->cn_probe; cp++) { ! 84: (*cp->cn_probe)(cp); ! 85: if (cp->cn_pri > CN_DEAD && ! 86: (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri)) ! 87: cn_tab = cp; ! 88: } ! 89: /* ! 90: * Found a console, initialize it. ! 91: */ ! 92: if (cp = cn_tab) { ! 93: /* ! 94: * Initialize as console ! 95: */ ! 96: (*cp->cn_init)(cp); ! 97: #ifdef MACH_KERNEL ! 98: /* ! 99: * Look up its dev_ops pointer in the device table and ! 100: * place it in the device indirection table. ! 101: */ ! 102: if (dev_name_lookup(cp->cn_name, &cn_ops, &x) == FALSE) ! 103: panic("cninit: dev_name_lookup failed"); ! 104: dev_set_indirection("console", cn_ops, minor(cp->cn_dev)); ! 105: #endif ! 106: #if CONSBUFSIZE > 0 ! 107: /* ! 108: * Now that the console is initialized, dump any chars in ! 109: * the temporary console buffer. ! 110: */ ! 111: if (consbufused) { ! 112: char *cbp = consbp; ! 113: do { ! 114: if (*cbp) ! 115: cnputc(*cbp); ! 116: if (++cbp == &consbuf[CONSBUFSIZE]) ! 117: cbp = consbuf; ! 118: } while (cbp != consbp); ! 119: consbufused = 0; ! 120: } ! 121: #endif ! 122: cn_inited = 1; ! 123: return; ! 124: } ! 125: /* ! 126: * No console device found, not a problem for BSD, fatal for Mach ! 127: */ ! 128: #ifdef MACH_KERNEL ! 129: panic("can't find a console device"); ! 130: #endif ! 131: } ! 132: ! 133: #ifndef MACH_KERNEL ! 134: cnopen(dev, flag) ! 135: dev_t dev; ! 136: { ! 137: if (cn_tab == NULL) ! 138: return(0); ! 139: dev = cn_tab->cn_dev; ! 140: return ((*cdevsw[major(dev)].d_open)(dev, flag)); ! 141: } ! 142: ! 143: cnclose(dev, flag) ! 144: dev_t dev; ! 145: { ! 146: if (cn_tab == NULL) ! 147: return(0); ! 148: dev = cn_tab->cn_dev; ! 149: return ((*cdevsw[major(dev)].d_close)(dev, flag)); ! 150: } ! 151: ! 152: cnread(dev, uio) ! 153: dev_t dev; ! 154: struct uio *uio; ! 155: { ! 156: if (cn_tab == NULL) ! 157: return(0); ! 158: dev = cn_tab->cn_dev; ! 159: return ((*cdevsw[major(dev)].d_read)(dev, uio)); ! 160: } ! 161: ! 162: cnwrite(dev, uio) ! 163: dev_t dev; ! 164: struct uio *uio; ! 165: { ! 166: if (cn_tab == NULL) ! 167: return(0); ! 168: dev = cn_tab->cn_dev; ! 169: return ((*cdevsw[major(dev)].d_write)(dev, uio)); ! 170: } ! 171: ! 172: cnioctl(dev, cmd, data, flag) ! 173: dev_t dev; ! 174: caddr_t data; ! 175: { ! 176: if (cn_tab == NULL) ! 177: return(0); ! 178: /* ! 179: * Superuser can always use this to wrest control of console ! 180: * output from the "virtual" console. ! 181: */ ! 182: if (cmd == TIOCCONS && constty) { ! 183: if (!suser()) ! 184: return(EPERM); ! 185: constty = NULL; ! 186: return(0); ! 187: } ! 188: dev = cn_tab->cn_dev; ! 189: return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag)); ! 190: } ! 191: ! 192: cnselect(dev, rw) ! 193: dev_t dev; ! 194: int rw; ! 195: { ! 196: if (cn_tab == NULL) ! 197: return(1); ! 198: return(ttselect(cn_tab->cn_dev, rw)); ! 199: } ! 200: ! 201: #ifndef hp300 ! 202: /* ! 203: * XXX Should go away when the new CIO MUX driver is in place ! 204: */ ! 205: #define d_control d_mmap ! 206: cncontrol(dev, cmd, data) ! 207: dev_t dev; ! 208: int cmd; ! 209: int data; ! 210: { ! 211: if (cn_tab == NULL) ! 212: return(0); ! 213: dev = cn_tab->cn_dev; ! 214: return((*cdevsw[major(dev)].d_control)(dev, cmd, data)); ! 215: } ! 216: #undef d_control ! 217: #endif ! 218: #endif ! 219: ! 220: cngetc() ! 221: { ! 222: if (cn_tab) ! 223: return ((*cn_tab->cn_getc)(cn_tab->cn_dev, 1)); ! 224: if (romgetc) ! 225: return ((*romgetc)(1)); ! 226: return (0); ! 227: } ! 228: ! 229: #ifdef MACH_KERNEL ! 230: cnmaygetc() ! 231: { ! 232: if (cn_tab) ! 233: return((*cn_tab->cn_getc)(cn_tab->cn_dev, 0)); ! 234: if (romgetc) ! 235: return ((*romgetc)(0)); ! 236: return (0); ! 237: } ! 238: #endif ! 239: ! 240: cnputc(c) ! 241: int c; ! 242: { ! 243: if (c == 0) ! 244: return; ! 245: ! 246: if (cn_tab) { ! 247: (*cn_tab->cn_putc)(cn_tab->cn_dev, c); ! 248: if (c == '\n') ! 249: (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r'); ! 250: } else if (romputc) { ! 251: (*romputc)(c); ! 252: if (c == '\n') ! 253: (*romputc)('\r'); ! 254: } ! 255: #if CONSBUFSIZE > 0 ! 256: else { ! 257: if (consbufused == 0) { ! 258: consbp = consbuf; ! 259: consbufused = 1; ! 260: bzero(consbuf, CONSBUFSIZE); ! 261: } ! 262: *consbp++ = c; ! 263: if (consbp >= &consbuf[CONSBUFSIZE]) ! 264: consbp = consbuf; ! 265: } ! 266: #endif ! 267: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.