xref: /netbsd-src/sys/dev/hpc/biconsdev.c (revision e7ae23fd9e39cd9acd02822d7b9d43eaf854d823)
1*e7ae23fdSchristos /*	$NetBSD: biconsdev.c,v 1.23 2015/08/20 14:40:18 christos Exp $	*/
29f7e4a2fSuch 
39f7e4a2fSuch /*-
49f7e4a2fSuch  * Copyright (c) 1999-2001
59f7e4a2fSuch  *         Shin Takemura and PocketBSD Project. All rights reserved.
69f7e4a2fSuch  *
79f7e4a2fSuch  * Redistribution and use in source and binary forms, with or without
89f7e4a2fSuch  * modification, are permitted provided that the following conditions
99f7e4a2fSuch  * are met:
109f7e4a2fSuch  * 1. Redistributions of source code must retain the above copyright
119f7e4a2fSuch  *    notice, this list of conditions and the following disclaimer.
129f7e4a2fSuch  * 2. Redistributions in binary form must reproduce the above copyright
139f7e4a2fSuch  *    notice, this list of conditions and the following disclaimer in the
149f7e4a2fSuch  *    documentation and/or other materials provided with the distribution.
159f7e4a2fSuch  * 3. All advertising materials mentioning features or use of this software
169f7e4a2fSuch  *    must display the following acknowledgement:
179f7e4a2fSuch  *	This product includes software developed by the PocketBSD project
189f7e4a2fSuch  *	and its contributors.
199f7e4a2fSuch  * 4. Neither the name of the project nor the names of its contributors
209f7e4a2fSuch  *    may be used to endorse or promote products derived from this software
219f7e4a2fSuch  *    without specific prior written permission.
229f7e4a2fSuch  *
239f7e4a2fSuch  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
249f7e4a2fSuch  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
259f7e4a2fSuch  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
269f7e4a2fSuch  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
279f7e4a2fSuch  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
289f7e4a2fSuch  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
299f7e4a2fSuch  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
309f7e4a2fSuch  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
319f7e4a2fSuch  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
329f7e4a2fSuch  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
339f7e4a2fSuch  * SUCH DAMAGE.
349f7e4a2fSuch  *
359f7e4a2fSuch  */
369f7e4a2fSuch /*
379f7e4a2fSuch  * Copyright (c) 1995
389f7e4a2fSuch  *	The Regents of the University of California.  All rights reserved.
399f7e4a2fSuch  *
409f7e4a2fSuch  * This code is derived from software contributed to Berkeley by
419f7e4a2fSuch  * Ted Lemon.
429f7e4a2fSuch  *
439f7e4a2fSuch  * Redistribution and use in source and binary forms, with or without
449f7e4a2fSuch  * modification, are permitted provided that the following conditions
459f7e4a2fSuch  * are met:
469f7e4a2fSuch  * 1. Redistributions of source code must retain the above copyright
479f7e4a2fSuch  *    notice, this list of conditions and the following disclaimer.
489f7e4a2fSuch  * 2. Redistributions in binary form must reproduce the above copyright
499f7e4a2fSuch  *    notice, this list of conditions and the following disclaimer in the
509f7e4a2fSuch  *    documentation and/or other materials provided with the distribution.
51aad01611Sagc  * 3. Neither the name of the University nor the names of its contributors
529f7e4a2fSuch  *    may be used to endorse or promote products derived from this software
539f7e4a2fSuch  *    without specific prior written permission.
549f7e4a2fSuch  *
559f7e4a2fSuch  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
569f7e4a2fSuch  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
579f7e4a2fSuch  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
589f7e4a2fSuch  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
599f7e4a2fSuch  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
609f7e4a2fSuch  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
619f7e4a2fSuch  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
629f7e4a2fSuch  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
639f7e4a2fSuch  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
649f7e4a2fSuch  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
659f7e4a2fSuch  * SUCH DAMAGE.
669f7e4a2fSuch  *
679f7e4a2fSuch  */
689f7e4a2fSuch 
69b84f53efSlukem #include <sys/cdefs.h>
70*e7ae23fdSchristos __KERNEL_RCSID(0, "$NetBSD: biconsdev.c,v 1.23 2015/08/20 14:40:18 christos Exp $");
71b84f53efSlukem 
729f7e4a2fSuch #include "biconsdev.h"
739f7e4a2fSuch #include <sys/param.h>
749f7e4a2fSuch #include <sys/proc.h>
759f7e4a2fSuch #include <sys/systm.h>
769f7e4a2fSuch #include <sys/buf.h>
779f7e4a2fSuch #include <sys/ioctl.h>
789f7e4a2fSuch #include <sys/tty.h>
799f7e4a2fSuch #include <sys/conf.h>
8052da0471Syamt #include <sys/kauth.h>
819f7e4a2fSuch 
829f7e4a2fSuch #include <dev/cons.h>
839f7e4a2fSuch #include <dev/hpc/bicons.h>
849f7e4a2fSuch #include <dev/hpc/biconsvar.h>
859f7e4a2fSuch 
86*e7ae23fdSchristos #include "ioconf.h"
87*e7ae23fdSchristos 
889f7e4a2fSuch struct tty biconsdev_tty[NBICONSDEV];
899f7e4a2fSuch static	void biconsdev_output(struct tty *);
909f7e4a2fSuch 
9177a6b82bSgehenna dev_type_open(biconsdevopen);
9277a6b82bSgehenna dev_type_close(biconsdevclose);
9377a6b82bSgehenna dev_type_read(biconsdevread);
9477a6b82bSgehenna dev_type_write(biconsdevwrite);
9577a6b82bSgehenna dev_type_ioctl(biconsdevioctl);
9677a6b82bSgehenna dev_type_tty(biconsdevtty);
9777a6b82bSgehenna dev_type_poll(biconsdevpoll);
9877a6b82bSgehenna 
9977a6b82bSgehenna const struct cdevsw biconsdev_cdevsw = {
100a68f9396Sdholland 	.d_open = biconsdevopen,
101a68f9396Sdholland 	.d_close = biconsdevclose,
102a68f9396Sdholland 	.d_read = biconsdevread,
103a68f9396Sdholland 	.d_write = biconsdevwrite,
104a68f9396Sdholland 	.d_ioctl = biconsdevioctl,
105a68f9396Sdholland 	.d_stop = nostop,
106a68f9396Sdholland 	.d_tty = biconsdevtty,
107a68f9396Sdholland 	.d_poll = biconsdevpoll,
108a68f9396Sdholland 	.d_mmap = nommap,
109a68f9396Sdholland 	.d_kqfilter = ttykqfilter,
110f9228f42Sdholland 	.d_discard = nodiscard,
111a68f9396Sdholland 	.d_flag = D_TTY
11277a6b82bSgehenna };
1139f7e4a2fSuch 
1149f7e4a2fSuch void
biconsdevattach(int n)1159f7e4a2fSuch biconsdevattach(int n)
1169f7e4a2fSuch {
1179f7e4a2fSuch 	struct tty *tp = &biconsdev_tty[0];
1189f7e4a2fSuch 	int maj;
1199f7e4a2fSuch 
1209f7e4a2fSuch 	/* locate the major number */
12177a6b82bSgehenna 	maj = cdevsw_lookup_major(&biconsdev_cdevsw);
1229f7e4a2fSuch 
1239f7e4a2fSuch 	/* Set up the tty queues now... */
1249f7e4a2fSuch 	clalloc(&tp->t_rawq, 1024, 1);
1259f7e4a2fSuch 	clalloc(&tp->t_canq, 1024, 1);
1269f7e4a2fSuch 	/* output queue doesn't need quoting */
1279f7e4a2fSuch 	clalloc(&tp->t_outq, 1024, 0);
1289f7e4a2fSuch 	/* Set default line discipline. */
1297d00e1afSthorpej 	tp->t_linesw = ttyldisc_default();
1309f7e4a2fSuch 
1319f7e4a2fSuch 
1329f7e4a2fSuch 	tp->t_dev = makedev(maj, 0);
1339f7e4a2fSuch 	tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
1349f7e4a2fSuch 	tp->t_param = (int (*)(struct tty *, struct termios *))nullop;
1359f7e4a2fSuch 	tp->t_winsize.ws_row = bicons_height;
1369f7e4a2fSuch 	tp->t_winsize.ws_col = bicons_width;
1379f7e4a2fSuch 	tp->t_winsize.ws_xpixel = bicons_xpixel;
1389f7e4a2fSuch 	tp->t_winsize.ws_ypixel = bicons_ypixel;
1399f7e4a2fSuch 	tp->t_oproc = biconsdev_output;
1409f7e4a2fSuch }
1419f7e4a2fSuch 
1429f7e4a2fSuch 
1439f7e4a2fSuch static void
biconsdev_output(struct tty * tp)1449f7e4a2fSuch biconsdev_output(struct tty *tp)
1459f7e4a2fSuch {
1469f7e4a2fSuch 	int s, n;
1479f7e4a2fSuch 	char buf[OBUFSIZ];
1489f7e4a2fSuch 
1499f7e4a2fSuch 	s = spltty();
1509f7e4a2fSuch 	if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) {
1519f7e4a2fSuch 		splx(s);
1529f7e4a2fSuch 		return;
1539f7e4a2fSuch 	}
1549f7e4a2fSuch 	tp->t_state |= TS_BUSY;
1559f7e4a2fSuch 	splx(s);
1569f7e4a2fSuch 	n = q_to_b(&tp->t_outq, buf, sizeof(buf));
1579f7e4a2fSuch 	bicons_putn(buf, n);
1589f7e4a2fSuch 
1599f7e4a2fSuch 	s = spltty();
1609f7e4a2fSuch 	tp->t_state &= ~TS_BUSY;
1619f7e4a2fSuch 	/* Come back if there's more to do */
162dc26833bSad 	if (ttypull(tp)) {
1639f7e4a2fSuch 		tp->t_state |= TS_TIMEOUT;
164d238692cSjoerg 		callout_schedule(&tp->t_rstrt_ch, 1);
1659f7e4a2fSuch 	}
1669f7e4a2fSuch 	splx(s);
1679f7e4a2fSuch }
1689f7e4a2fSuch 
1699f7e4a2fSuch 
1709f7e4a2fSuch int
biconsdevopen(dev_t dev,int flag,int mode,struct lwp * l)17195e1ffb1Schristos biconsdevopen(dev_t dev, int flag, int mode, struct lwp *l)
1729f7e4a2fSuch {
1739f7e4a2fSuch 	struct tty *tp = &biconsdev_tty[0];
1749f7e4a2fSuch 	int status;
1759f7e4a2fSuch 
176bdc51baeSelad 	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
177bdc51baeSelad 		return (EBUSY);
178bdc51baeSelad 
1799f7e4a2fSuch 	if ((tp->t_state & TS_ISOPEN) == 0) {
1809f7e4a2fSuch 		/*
1819f7e4a2fSuch 		 * Leave baud rate alone!
1829f7e4a2fSuch 		 */
1839f7e4a2fSuch 		ttychars(tp);
1849f7e4a2fSuch 		tp->t_iflag = TTYDEF_IFLAG;
1859f7e4a2fSuch 		tp->t_oflag = TTYDEF_OFLAG;
1869f7e4a2fSuch 		tp->t_lflag = TTYDEF_LFLAG;
1879f7e4a2fSuch 		tp->t_cflag = TTYDEF_CFLAG;
1889f7e4a2fSuch 		tp->t_state = TS_ISOPEN | TS_CARR_ON;
1899f7e4a2fSuch 		(void)(*tp->t_param)(tp, &tp->t_termios);
1909f7e4a2fSuch 		ttsetwater(tp);
191bdc51baeSelad 	}
1929f7e4a2fSuch 
1939f7e4a2fSuch 	status = (*tp->t_linesw->l_open)(dev, tp);
1949f7e4a2fSuch 	return status;
1959f7e4a2fSuch }
1969f7e4a2fSuch 
1979f7e4a2fSuch 
1989f7e4a2fSuch int
biconsdevclose(dev_t dev,int flag,int mode,struct lwp * l)19995e1ffb1Schristos biconsdevclose(dev_t dev, int flag, int mode, struct lwp *l)
2009f7e4a2fSuch {
2019f7e4a2fSuch 	struct tty *tp = &biconsdev_tty[0];
2029f7e4a2fSuch 
2039f7e4a2fSuch 	(*tp->t_linesw->l_close)(tp, flag);
2049f7e4a2fSuch 	ttyclose(tp);
2059f7e4a2fSuch 
2069f7e4a2fSuch 	return (0);
2079f7e4a2fSuch }
2089f7e4a2fSuch 
2099f7e4a2fSuch 
2109f7e4a2fSuch int
biconsdevread(dev_t dev,struct uio * uio,int flag)2119f7e4a2fSuch biconsdevread(dev_t dev, struct uio *uio, int flag)
2129f7e4a2fSuch {
2139f7e4a2fSuch 	struct tty *tp = &biconsdev_tty[0];
2149f7e4a2fSuch 
2159f7e4a2fSuch 	return ((*tp->t_linesw->l_read)(tp, uio, flag));
2169f7e4a2fSuch }
2179f7e4a2fSuch 
2189f7e4a2fSuch 
2199f7e4a2fSuch int
biconsdevwrite(dev_t dev,struct uio * uio,int flag)2209f7e4a2fSuch biconsdevwrite(dev_t dev, struct uio *uio, int flag)
2219f7e4a2fSuch {
2229f7e4a2fSuch 	struct tty *tp = &biconsdev_tty[0];
2239f7e4a2fSuch 
2249f7e4a2fSuch 	return ((*tp->t_linesw->l_write)(tp, uio, flag));
2259f7e4a2fSuch }
2269f7e4a2fSuch 
2279f7e4a2fSuch 
2282963ff5cSscw int
biconsdevpoll(dev_t dev,int events,struct lwp * l)22995e1ffb1Schristos biconsdevpoll(dev_t dev, int events, struct lwp *l)
2302963ff5cSscw {
2312963ff5cSscw 	struct tty *tp = &biconsdev_tty[0];
2322963ff5cSscw 
23395e1ffb1Schristos 	return ((*tp->t_linesw->l_poll)(tp, events, l));
2342963ff5cSscw }
2352963ff5cSscw 
2362963ff5cSscw 
2379f7e4a2fSuch struct tty *
biconsdevtty(dev_t dev)2389f7e4a2fSuch biconsdevtty(dev_t dev)
2399f7e4a2fSuch {
2409f7e4a2fSuch 	struct tty *tp = &biconsdev_tty[0];
2419f7e4a2fSuch 
2429f7e4a2fSuch         return (tp);
2439f7e4a2fSuch }
2449f7e4a2fSuch 
2459f7e4a2fSuch int
biconsdevioctl(dev_t dev,u_long cmd,void * data,int flag,struct lwp * l)24653524e44Schristos biconsdevioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
2479f7e4a2fSuch {
2489f7e4a2fSuch 	struct tty *tp = &biconsdev_tty[0];
2499f7e4a2fSuch 	int error;
2509f7e4a2fSuch 
25195e1ffb1Schristos 	if ((error = tp->t_linesw->l_ioctl(tp, cmd, data, flag, l)) !=
25231144d99Satatat 	    EPASSTHROUGH)
2539f7e4a2fSuch 		return (error);
25495e1ffb1Schristos 	return (ttioctl(tp, cmd, data, flag, l));
2559f7e4a2fSuch }
256