Sun Dec 11 22:34:42 2011 UTC ()
make ttycons a proper tty device, now it can be the console


(jmcneill)
diff -r1.3 -r1.4 src/sys/arch/usermode/conf/majors.usermode
diff -r1.7 -r1.8 src/sys/arch/usermode/dev/ttycons.c

cvs diff -r1.3 -r1.4 src/sys/arch/usermode/conf/majors.usermode (expand / switch to unified diff)

--- src/sys/arch/usermode/conf/majors.usermode 2011/08/25 11:06:29 1.3
+++ src/sys/arch/usermode/conf/majors.usermode 2011/12/11 22:34:42 1.4
@@ -1,14 +1,15 @@ @@ -1,14 +1,15 @@
1# $NetBSD: majors.usermode,v 1.3 2011/08/25 11:06:29 jmcneill Exp $ 1# $NetBSD: majors.usermode,v 1.4 2011/12/11 22:34:42 jmcneill Exp $
2 2
3device-major cons char 0 3device-major cons char 0
4device-major ctty char 1 4device-major ctty char 1
5device-major mem char 2 5device-major mem char 2
6#device-major wd char 3 6#device-major wd char 3
7device-major swap char 4 block 1 vmswap 7device-major swap char 4 block 1 vmswap
8device-major pts char 5 pty 8device-major pts char 5 pty
9device-major ptc char 6 pty 9device-major ptc char 6 pty
10device-major log char 7 10device-major log char 7
11device-major com char 8 com 11device-major com char 8 com
12device-major md char 24 block 17 md 12device-major md char 24 block 17 md
13device-major wsdisplay char 47 wsdisplay 13device-major wsdisplay char 47 wsdisplay
14device-major ld char 69 block 19 ld 14device-major ld char 69 block 19 ld
 15device-major ttycons char 159 ttycons

cvs diff -r1.7 -r1.8 src/sys/arch/usermode/dev/ttycons.c (expand / switch to unified diff)

--- src/sys/arch/usermode/dev/ttycons.c 2011/12/11 20:43:03 1.7
+++ src/sys/arch/usermode/dev/ttycons.c 2011/12/11 22:34:42 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ttycons.c,v 1.7 2011/12/11 20:43:03 jmcneill Exp $ */ 1/* $NetBSD: ttycons.c,v 1.8 2011/12/11 22:34:42 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,84 +17,135 @@ @@ -17,84 +17,135 @@
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: ttycons.c,v 1.7 2011/12/11 20:43:03 jmcneill Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: ttycons.c,v 1.8 2011/12/11 22:34:42 jmcneill Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
 33#include <sys/conf.h>
33#include <sys/proc.h> 34#include <sys/proc.h>
34#include <sys/systm.h> 35#include <sys/systm.h>
35#include <sys/device.h> 36#include <sys/device.h>
 37#include <sys/kauth.h>
36#include <sys/termios.h> 38#include <sys/termios.h>
 39#include <sys/tty.h>
37 40
38#include <dev/cons.h> 41#include <dev/cons.h>
39 42
40#include <machine/mainbus.h> 43#include <machine/mainbus.h>
41#include <machine/thunk.h> 44#include <machine/thunk.h>
42 45
43static int ttycons_match(device_t, cfdata_t, void *); 46static int ttycons_match(device_t, cfdata_t, void *);
44static void ttycons_attach(device_t, device_t, void *); 47static void ttycons_attach(device_t, device_t, void *);
45 48
46void ttycons_consinit(void); 49void ttycons_consinit(void);
47 50
48typedef struct ttycons_softc { 51struct ttycons_softc {
49 device_t sc_dev; 52 device_t sc_dev;
50} ttycons_softc_t; 53 struct tty *sc_tty;
 54 void *sc_rd_sih;
 55};
51 56
52dev_type_cngetc(ttycons_cngetc); 57dev_type_cngetc(ttycons_cngetc);
53dev_type_cnputc(ttycons_cnputc); 58dev_type_cnputc(ttycons_cnputc);
54dev_type_cnpollc(ttycons_cnpollc); 59dev_type_cnpollc(ttycons_cnpollc);
55 60
56static struct cnm_state ttycons_cnm_state; 61static struct cnm_state ttycons_cnm_state;
57struct consdev ttycons_consdev = { 62struct consdev ttycons_consdev = {
58 .cn_getc = ttycons_cngetc, 63 .cn_getc = ttycons_cngetc,
59 .cn_putc = ttycons_cnputc, 64 .cn_putc = ttycons_cnputc,
60 .cn_pollc = ttycons_cnpollc, 65 .cn_pollc = ttycons_cnpollc,
61 .cn_dev = NODEV, 66 .cn_dev = NODEV,
62 .cn_pri = CN_NORMAL, 67 .cn_pri = CN_NORMAL,
63}; 68};
64 69
65CFATTACH_DECL_NEW(ttycons, sizeof(ttycons_softc_t), 70CFATTACH_DECL_NEW(ttycons, sizeof(struct ttycons_softc),
66 ttycons_match, ttycons_attach, NULL, NULL); 71 ttycons_match, ttycons_attach, NULL, NULL);
67 72
 73extern struct cfdriver ttycons_cd;
 74
 75dev_type_open(ttycons_open);
 76dev_type_close(ttycons_close);
 77dev_type_read(ttycons_read);
 78dev_type_write(ttycons_write);
 79dev_type_ioctl(ttycons_ioctl);
 80dev_type_stop(ttycons_stop);
 81dev_type_tty(ttycons_tty);
 82dev_type_poll(ttycons_poll);
 83
 84const struct cdevsw ttycons_cdevsw = {
 85 .d_open = ttycons_open,
 86 .d_close = ttycons_close,
 87 .d_read = ttycons_read,
 88 .d_write = ttycons_write,
 89 .d_ioctl = ttycons_ioctl,
 90 .d_stop = ttycons_stop,
 91 .d_tty = ttycons_tty,
 92 .d_poll = ttycons_poll,
 93 .d_kqfilter = ttykqfilter,
 94 .d_flag = D_TTY,
 95};
 96
 97static void ttycons_start(struct tty *);
 98static int ttycons_param(struct tty *, struct termios *);
 99
 100static void ttycons_intr(int);
 101static void ttycons_softintr(void *);
 102
68static int 103static int
69ttycons_match(device_t parent, cfdata_t match, void *opaque) 104ttycons_match(device_t parent, cfdata_t match, void *opaque)
70{ 105{
71 struct thunkbus_attach_args *taa = opaque; 106 struct thunkbus_attach_args *taa = opaque;
72 107
73 if (taa->taa_type != THUNKBUS_TYPE_TTYCONS) 108 if (taa->taa_type != THUNKBUS_TYPE_TTYCONS)
74 return 0; 109 return 0;
75 110
76 return 1; 111 return 1;
77} 112}
78 113
79static void 114static void
80ttycons_attach(device_t parent, device_t self, void *opaque) 115ttycons_attach(device_t parent, device_t self, void *opaque)
81{ 116{
82 ttycons_softc_t *sc = device_private(self); 117 struct ttycons_softc *sc = device_private(self);
 118 int maj;
83 119
84 aprint_naive("\n"); 120 aprint_naive("\n");
85 aprint_normal(": console\n"); 121 aprint_normal(": console\n");
86 122
87 sc->sc_dev = self; 123 sc->sc_dev = self;
 124 sc->sc_tty = tty_alloc();
 125 tty_attach(sc->sc_tty);
 126 sc->sc_tty->t_oproc = ttycons_start;
 127 sc->sc_tty->t_param = ttycons_param;
 128
 129 maj = cdevsw_lookup_major(&ttycons_cdevsw);
 130 cn_tab->cn_dev = makedev(maj, device_unit(self));
 131 sc->sc_tty->t_dev = cn_tab->cn_dev;
 132
 133 sc->sc_rd_sih = softint_establish(SOFTINT_SERIAL,
 134 ttycons_softintr, sc);
 135 if (sc->sc_rd_sih == NULL)
 136 panic("couldn't establish ttycons softint handler\n");
 137
 138 thunk_signal(SIGIO, ttycons_intr);
88} 139}
89 140
90void 141void
91ttycons_consinit(void) 142ttycons_consinit(void)
92{ 143{
93 struct thunk_termios t; 144 struct thunk_termios t;
94 145
95 thunk_tcgetattr(0, &t); 146 thunk_tcgetattr(0, &t);
96 t.c_lflag &= ~(ECHO|ICANON); 147 t.c_lflag &= ~(ECHO|ICANON);
97 t.c_cc[VTIME] = 0; 148 t.c_cc[VTIME] = 0;
98 t.c_cc[VMIN] = 1; 149 t.c_cc[VMIN] = 1;
99 thunk_tcsetattr(0, TCSANOW, &t); 150 thunk_tcsetattr(0, TCSANOW, &t);
100 151
@@ -109,13 +160,197 @@ ttycons_cngetc(dev_t dev) @@ -109,13 +160,197 @@ ttycons_cngetc(dev_t dev)
109 return thunk_getchar(); 160 return thunk_getchar();
110} 161}
111 162
112void 163void
113ttycons_cnputc(dev_t dev, int c) 164ttycons_cnputc(dev_t dev, int c)
114{ 165{
115 thunk_putchar(c); 166 thunk_putchar(c);
116} 167}
117 168
118void 169void
119ttycons_cnpollc(dev_t dev, int on) 170ttycons_cnpollc(dev_t dev, int on)
120{ 171{
121} 172}
 173
 174int
 175ttycons_open(dev_t dev, int flag, int mode, lwp_t *l)
 176{
 177 struct ttycons_softc *sc;
 178 struct tty *t;
 179
 180 sc = device_lookup_private(&ttycons_cd, minor(dev));
 181 if (sc == NULL)
 182 return ENXIO;
 183 t = sc->sc_tty;
 184
 185 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, t))
 186 return EBUSY;
 187
 188 if ((t->t_state & TS_ISOPEN) == 0 && t->t_wopen == 0) {
 189 t->t_dev = dev;
 190 ttychars(t);
 191 t->t_iflag = TTYDEF_IFLAG;
 192 t->t_oflag = TTYDEF_OFLAG;
 193 t->t_cflag = TTYDEF_CFLAG;
 194 t->t_lflag = TTYDEF_LFLAG;
 195 t->t_ispeed = t->t_ospeed = TTYDEF_SPEED;
 196 ttycons_param(t, &t->t_termios);
 197 ttsetwater(t);
 198 }
 199 t->t_state |= TS_CARR_ON;
 200
 201 return t->t_linesw->l_open(dev, t);
 202}
 203
 204int
 205ttycons_close(dev_t dev, int flag, int mode, lwp_t *l)
 206{
 207 struct ttycons_softc *sc;
 208 struct tty *t;
 209
 210 sc = device_lookup_private(&ttycons_cd, minor(dev));
 211 t = sc->sc_tty;
 212
 213 if (t == NULL)
 214 return 0;
 215
 216 t->t_linesw->l_close(t, flag);
 217 ttyclose(t);
 218
 219 return 0;
 220}
 221
 222int
 223ttycons_read(dev_t dev, struct uio *uio, int flag)
 224{
 225 struct ttycons_softc *sc;
 226 struct tty *t;
 227
 228 sc = device_lookup_private(&ttycons_cd, minor(dev));
 229 t = sc->sc_tty;
 230
 231 return t->t_linesw->l_read(t, uio, flag);
 232}
 233
 234int
 235ttycons_write(dev_t dev, struct uio *uio, int flag)
 236{
 237 struct ttycons_softc *sc;
 238 struct tty *t;
 239
 240 sc = device_lookup_private(&ttycons_cd, minor(dev));
 241 t = sc->sc_tty;
 242
 243 return t->t_linesw->l_write(t, uio, flag);
 244}
 245
 246int
 247ttycons_poll(dev_t dev, int events, lwp_t *l)
 248{
 249 struct ttycons_softc *sc;
 250 struct tty *t;
 251
 252 sc = device_lookup_private(&ttycons_cd, minor(dev));
 253 t = sc->sc_tty;
 254
 255 return t->t_linesw->l_poll(t, events, l);
 256}
 257
 258struct tty *
 259ttycons_tty(dev_t dev)
 260{
 261 struct ttycons_softc *sc;
 262
 263 sc = device_lookup_private(&ttycons_cd, minor(dev));
 264
 265 return sc->sc_tty;
 266}
 267
 268int
 269ttycons_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
 270{
 271 struct ttycons_softc *sc;
 272 struct tty *t;
 273 int error;
 274
 275 sc = device_lookup_private(&ttycons_cd, minor(dev));
 276 t = sc->sc_tty;
 277
 278 error = t->t_linesw->l_ioctl(t, cmd, data, flag, l);
 279 if (error != EPASSTHROUGH)
 280 return error;
 281
 282 error = ttioctl(t, cmd, data, flag, l);
 283 if (error != EPASSTHROUGH)
 284 return error;
 285
 286 return EPASSTHROUGH;
 287}
 288
 289static void
 290ttycons_start(struct tty *t)
 291{
 292 u_char buf[64+1];
 293 int s, len, i;
 294
 295 s = spltty();
 296 if (t->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
 297 splx(s);
 298 return;
 299 }
 300 t->t_state |= TS_BUSY;
 301 splx(s);
 302
 303 len = q_to_b(&t->t_outq, buf, sizeof(buf) - 1);
 304 for (i = 0; i < len; i++) {
 305 thunk_putchar(buf[i]);
 306 }
 307
 308 s = spltty();
 309 t->t_state &= ~TS_BUSY;
 310 if (ttypull(t)) {
 311 t->t_state |= TS_TIMEOUT;
 312 callout_schedule(&t->t_rstrt_ch, 1);
 313 }
 314 splx(s);
 315}
 316
 317void
 318ttycons_stop(struct tty *t, int flag)
 319{
 320}
 321
 322static int
 323ttycons_param(struct tty *t, struct termios *c)
 324{
 325 t->t_ispeed = c->c_ispeed;
 326 t->t_ospeed = c->c_ospeed;
 327 t->t_cflag = c->c_cflag;
 328 return 0;
 329}
 330
 331static void
 332ttycons_intr(int sig)
 333{
 334 struct ttycons_softc *sc;
 335
 336 sc = device_lookup_private(&ttycons_cd, minor(cn_tab->cn_dev));
 337 if (sc == NULL)
 338 return;
 339
 340 softint_schedule(sc->sc_rd_sih);
 341}
 342
 343static void
 344ttycons_softintr(void *priv)
 345{
 346 struct ttycons_softc *sc = priv;
 347 struct tty *t = sc->sc_tty;
 348 unsigned char ch;
 349 int c;
 350
 351 while ((c = thunk_pollchar()) >= 0) {
 352 ch = (unsigned char)c;
 353 cn_check_magic(t->t_dev, ch, ttycons_cnm_state);
 354 t->t_linesw->l_rint(ch, t);
 355 }
 356}