1*80f6fc52Srmind /* $NetBSD: nullcons_subr.c,v 1.11 2011/04/24 16:26:59 rmind Exp $ */ 261da4642Scdi 361da4642Scdi /*- 461da4642Scdi * Copyright (c) 2003 The NetBSD Foundation, Inc. 561da4642Scdi * All rights reserved. 661da4642Scdi * 761da4642Scdi * Redistribution and use in source and binary forms, with or without 861da4642Scdi * modification, are permitted provided that the following conditions 961da4642Scdi * are met: 1061da4642Scdi * 1. Redistributions of source code must retain the above copyright 1161da4642Scdi * notice, this list of conditions and the following disclaimer. 1261da4642Scdi * 2. Redistributions in binary form must reproduce the above copyright 1361da4642Scdi * notice, this list of conditions and the following disclaimer in the 1461da4642Scdi * documentation and/or other materials provided with the distribution. 1561da4642Scdi * 1661da4642Scdi * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1761da4642Scdi * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1861da4642Scdi * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1961da4642Scdi * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2061da4642Scdi * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2161da4642Scdi * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2261da4642Scdi * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2361da4642Scdi * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2461da4642Scdi * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2561da4642Scdi * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2661da4642Scdi * POSSIBILITY OF SUCH DAMAGE. 2761da4642Scdi */ 2861da4642Scdi 2961da4642Scdi #include <sys/cdefs.h> 30*80f6fc52Srmind __KERNEL_RCSID(0, "$NetBSD: nullcons_subr.c,v 1.11 2011/04/24 16:26:59 rmind Exp $"); 3161da4642Scdi 3261da4642Scdi #include <sys/param.h> 3361da4642Scdi #include <sys/proc.h> 3461da4642Scdi #include <sys/systm.h> 3561da4642Scdi #include <sys/buf.h> 3661da4642Scdi #include <sys/ioctl.h> 3761da4642Scdi #include <sys/tty.h> 3861da4642Scdi #include <sys/file.h> 3961da4642Scdi #include <sys/conf.h> 4061da4642Scdi #include <sys/vnode.h> 4161da4642Scdi 4261da4642Scdi #include <dev/cons.h> 4361da4642Scdi 4461da4642Scdi static struct tty *nulltty; /* null console tty */ 4561da4642Scdi 4661da4642Scdi cons_decl(null); 4761da4642Scdi 4861da4642Scdi dev_type_read(nullcndev_read); 4961da4642Scdi dev_type_ioctl(nullcndev_ioctl); 5061da4642Scdi dev_type_tty(nullcndev_tty); 5161da4642Scdi 5218db93c7Sperry static int nullcons_newdev(struct consdev *); 5361da4642Scdi 5461da4642Scdi const struct cdevsw nullcn_devsw = { 5561da4642Scdi nullopen, nullclose, nullcndev_read, nullwrite, nullcndev_ioctl, 5661da4642Scdi nullstop, nullcndev_tty, nopoll, nommap, ttykqfilter, D_TTY 5761da4642Scdi }; 5861da4642Scdi 5961da4642Scdi /* 6061da4642Scdi * null console device. We need it because of the ioctl() it handles, 6161da4642Scdi * which in particular allows control terminal allocation through 6261da4642Scdi * TIOCSCTTY ioctl. Without the latter, system won't even boot past init(8) 6361da4642Scdi * invocation. 6461da4642Scdi */ 6561da4642Scdi int 66454af1c0Sdsl nullcndev_read(dev_t dev, struct uio *uio, int flag) 6761da4642Scdi { 6861da4642Scdi 6913a1c5a1Stsutsui return EIO; 7061da4642Scdi } 7161da4642Scdi 7261da4642Scdi int 73454af1c0Sdsl nullcndev_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 7461da4642Scdi { 7561da4642Scdi int error; 7661da4642Scdi 7795e1ffb1Schristos error = (*nulltty->t_linesw->l_ioctl)(nulltty, cmd, data, flag, l); 7861da4642Scdi if (error != EPASSTHROUGH) 7939014001Stsutsui return error; 8061da4642Scdi 8195e1ffb1Schristos error = ttioctl(nulltty, cmd, data, flag, l); 8261da4642Scdi if (error != EPASSTHROUGH) 8339014001Stsutsui return error; 8461da4642Scdi 8539014001Stsutsui return 0; 8661da4642Scdi } 8761da4642Scdi 8861da4642Scdi struct tty* 89454af1c0Sdsl nullcndev_tty(dev_t dev) 9061da4642Scdi { 9161da4642Scdi 9261da4642Scdi return nulltty; 9361da4642Scdi } 9461da4642Scdi 9561da4642Scdi /* 9661da4642Scdi * Mark console as no-op (null) console. Proper initialization is deferred 9761da4642Scdi * to nullconsattach(). 9861da4642Scdi */ 9961da4642Scdi void 100454af1c0Sdsl nullcnprobe(struct consdev *cn) 10161da4642Scdi { 10261da4642Scdi 10361da4642Scdi cn->cn_pri = CN_NULL; 10461da4642Scdi cn->cn_dev = NODEV; 10561da4642Scdi } 10661da4642Scdi 10761da4642Scdi /* 10861da4642Scdi * null console initialization. This includes allocation of a new device and 10961da4642Scdi * a new tty. 11061da4642Scdi */ 11161da4642Scdi void 112454af1c0Sdsl nullcninit(struct consdev *cn) 11361da4642Scdi { 11461da4642Scdi static struct consdev nullcn = cons_init(null); 11561da4642Scdi 11661da4642Scdi nullcnprobe(&nullcn); 11761da4642Scdi cn_tab = &nullcn; 11861da4642Scdi } 11961da4642Scdi 12061da4642Scdi /* 12161da4642Scdi * Dumb getc() implementation. Simply blocks on call. 12261da4642Scdi */ 12361da4642Scdi int 124454af1c0Sdsl nullcngetc(dev_t dev) 12561da4642Scdi { 12661da4642Scdi 12739014001Stsutsui for (;;) 12839014001Stsutsui ; 12939014001Stsutsui return 0; 13061da4642Scdi } 13161da4642Scdi 13261da4642Scdi /* 13361da4642Scdi * Dumb putc() implementation. 13461da4642Scdi */ 13561da4642Scdi void 136454af1c0Sdsl nullcnputc(dev_t dev, int c) 13761da4642Scdi { 13861da4642Scdi 13961da4642Scdi } 14061da4642Scdi 14161da4642Scdi /* 14261da4642Scdi * Allocate a new console device and a tty to handle console ioctls. 14361da4642Scdi */ 14461da4642Scdi int 145454af1c0Sdsl nullcons_newdev(struct consdev *cn) 14661da4642Scdi { 14761da4642Scdi int error; 14861da4642Scdi int bmajor = -1, cmajor = -1; 14961da4642Scdi 15061da4642Scdi if ((cn == NULL) || (cn->cn_pri != CN_NULL) || (cn->cn_dev != NODEV)) 15139014001Stsutsui return 0; 15261da4642Scdi 15361da4642Scdi /* 15461da4642Scdi * Attach no-op device to the device list. 15561da4642Scdi */ 15661da4642Scdi error = devsw_attach("nullcn", NULL, &bmajor, &nullcn_devsw, &cmajor); 15761da4642Scdi if (error != 0) 15839014001Stsutsui return error; 15961da4642Scdi 16061da4642Scdi /* 16161da4642Scdi * Allocate tty (mostly to have sane ioctl()). 16261da4642Scdi */ 163*80f6fc52Srmind nulltty = tty_alloc(); 16461da4642Scdi nulltty->t_dev = makedev(cmajor, 0); 16561da4642Scdi tty_attach(nulltty); 16661da4642Scdi cn->cn_dev = nulltty->t_dev; 16761da4642Scdi 16839014001Stsutsui return 0; 16961da4642Scdi } 17061da4642Scdi 17161da4642Scdi /* 17261da4642Scdi * Pseudo-device attach function -- it's the right time to do the rest of 17361da4642Scdi * initialization. 17461da4642Scdi */ 17561da4642Scdi void 176454af1c0Sdsl nullconsattach(int pdev_count) 17761da4642Scdi { 17861da4642Scdi 17961da4642Scdi nullcons_newdev(cn_tab); 18061da4642Scdi } 181