1/* 2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29/* 30 * Indirect driver for console 31 * 32 * The purpose of this driver is to provide a device node indirection for 33 * the console device, which can be any tty class device. It does this by 34 * externalizing a global pointer "constty", which is then pointed at the 35 * console tty device. 36 * 37 * The default for this pointer is uninitialized; when it is NULL, we fall 38 * back to the "km" device, which is a tty BSD wrapper device for the 39 * Platform Expert console device. When it is non-NULL, we call through 40 * to the tty device device instead. 41 * 42 * The registration for this device node is static, and the devfs init 43 * code does not externalize a named device for it, to avoid software 44 * seeing the device and trying to open it. 45 * 46 * The upshot of this is that the console driver should not be set as your 47 * controlling tty, since you will get a reference to a device which does 48 * not have an actual device node in /dev, so its name cannot be looked up. 49 */ 50#include <sys/param.h> 51#include <sys/systm.h> 52#include <sys/conf.h> 53#include <sys/ioctl.h> 54#include <sys/tty.h> 55#include <sys/proc.h> 56#include <sys/uio.h> 57 58struct tty *constty; /* current console device */ 59 60/* 61 * The km driver supplied the default console device for the systems 62 * (usually a raw frame buffer driver, but potentially a serial driver). 63 */ 64extern struct tty *km_tty[1]; 65 66/* 67 * cdevsw[] entries for the console device driver 68 */ 69int cnopen(__unused dev_t dev, int flag, int devtype, proc_t pp); 70int cnclose(__unused dev_t dev, int flag, int mode, proc_t pp); 71int cnread(__unused dev_t dev, struct uio *uio, int ioflag); 72int cnwrite(__unused dev_t dev, struct uio *uio, int ioflag); 73int cnioctl(__unused dev_t dev, u_long cmd, caddr_t addr, int flg, proc_t p); 74int cnselect(__unused dev_t dev, int flag, void * wql, proc_t p); 75 76static dev_t 77cndev(void) 78{ 79 if (constty) 80 return constty->t_dev; 81 else 82 return km_tty[0]->t_dev; 83} 84 85int 86cnopen(__unused dev_t dev, int flag, int devtype, struct proc *pp) 87{ 88 dev = cndev(); 89 return ((*cdevsw[major(dev)].d_open)(dev, flag, devtype, pp)); 90} 91 92 93int 94cnclose(__unused dev_t dev, int flag, int mode, struct proc *pp) 95{ 96 dev = cndev(); 97 return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, pp)); 98} 99 100 101int 102cnread(__unused dev_t dev, struct uio *uio, int ioflag) 103{ 104 dev = cndev(); 105 return ((*cdevsw[major(dev)].d_read)(dev, uio, ioflag)); 106} 107 108 109int 110cnwrite(__unused dev_t dev, struct uio *uio, int ioflag) 111{ 112 dev = cndev(); 113 return ((*cdevsw[major(dev)].d_write)(dev, uio, ioflag)); 114} 115 116 117int 118cnioctl(__unused dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 119{ 120 dev = cndev(); 121#if 0 122 /* 123 * Superuser can always use this to wrest control of console 124 * output from the "virtual" console. 125 * 126 * XXX Unfortunately, this code doesn't do what the author thougt 127 * XXX it did; use of the console device, a TIOCCONS would always 128 * XXX disassociate the console from a virtual terminal and send 129 * XXX it back to the fake tty. 130 */ 131 if ((unsigned) cmd == TIOCCONS && constty) { 132 int error = proc_suser(p); 133 if (!error) { 134 constty = NULL; 135 } 136 return(error); 137 } 138#endif /* 0 */ 139 140 return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, addr, flag, p)); 141} 142 143 144int 145cnselect(__unused dev_t dev, int flag, void *wql, struct proc *p) 146{ 147 dev = cndev(); 148 return ((*cdevsw[major(dev)].d_select)(dev, flag, wql, p)); 149} 150