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