summaryrefslogtreecommitdiffstats
path: root/sys/dev/syscons
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2008-08-20 08:31:58 +0000
committered <ed@FreeBSD.org>2008-08-20 08:31:58 +0000
commitcc3116a9380fe32a751b584f3d8083698ccfba15 (patch)
treebd0c08a66997254385160ce71ea32029b99f99f9 /sys/dev/syscons
parentb49301b5cd9ff43a7af0bd9054d9d1a328c0d212 (diff)
downloadFreeBSD-src-cc3116a9380fe32a751b584f3d8083698ccfba15.zip
FreeBSD-src-cc3116a9380fe32a751b584f3d8083698ccfba15.tar.gz
Integrate the new MPSAFE TTY layer to the FreeBSD operating system.
The last half year I've been working on a replacement TTY layer for the FreeBSD kernel. The new TTY layer was designed to improve the following: - Improved driver model: The old TTY layer has a driver model that is not abstract enough to make it friendly to use. A good example is the output path, where the device drivers directly access the output buffers. This means that an in-kernel PPP implementation must always convert network buffers into TTY buffers. If a PPP implementation would be built on top of the new TTY layer (still needs a hooks layer, though), it would allow the PPP implementation to directly hand the data to the TTY driver. - Improved hotplugging: With the old TTY layer, it isn't entirely safe to destroy TTY's from the system. This implementation has a two-step destructing design, where the driver first abandons the TTY. After all threads have left the TTY, the TTY layer calls a routine in the driver, which can be used to free resources (unit numbers, etc). The pts(4) driver also implements this feature, which means posix_openpt() will now return PTY's that are created on the fly. - Improved performance: One of the major improvements is the per-TTY mutex, which is expected to improve scalability when compared to the old Giant locking. Another change is the unbuffered copying to userspace, which is both used on TTY device nodes and PTY masters. Upgrading should be quite straightforward. Unlike previous versions, existing kernel configuration files do not need to be changed, except when they reference device drivers that are listed in UPDATING. Obtained from: //depot/projects/mpsafetty/... Approved by: philip (ex-mentor) Discussed: on the lists, at BSDCan, at the DevSummit Sponsored by: Snow B.V., the Netherlands dcons(4) fixed by: kan
Diffstat (limited to 'sys/dev/syscons')
-rw-r--r--sys/dev/syscons/schistory.c7
-rw-r--r--sys/dev/syscons/scmouse.c5
-rw-r--r--sys/dev/syscons/scterm-sc.c2
-rw-r--r--sys/dev/syscons/scvesactl.c12
-rw-r--r--sys/dev/syscons/scvidctl.c18
-rw-r--r--sys/dev/syscons/syscons.c327
-rw-r--r--sys/dev/syscons/syscons.h24
-rw-r--r--sys/dev/syscons/sysmouse.c135
8 files changed, 219 insertions, 311 deletions
diff --git a/sys/dev/syscons/schistory.c b/sys/dev/syscons/schistory.c
index 860e8f9..860367b 100644
--- a/sys/dev/syscons/schistory.c
+++ b/sys/dev/syscons/schistory.c
@@ -291,8 +291,7 @@ sc_hist_down_line(scr_stat *scp)
}
int
-sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
- struct thread *td)
+sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
scr_stat *scp;
int error;
@@ -300,7 +299,7 @@ sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
switch (cmd) {
case CONS_HISTORY: /* set history size */
- scp = SC_STAT(tp->t_dev);
+ scp = SC_STAT(tp);
if (*(int *)data <= 0)
return EINVAL;
if (scp->status & BUFFER_SAVED)
@@ -315,7 +314,7 @@ sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
return error;
case CONS_CLRHIST:
- scp = SC_STAT(tp->t_dev);
+ scp = SC_STAT(tp);
sc_vtb_clear(scp->history, scp->sc->scr_map[0x20],
SC_NORM_ATTR << 8);
return 0;
diff --git a/sys/dev/syscons/scmouse.c b/sys/dev/syscons/scmouse.c
index 25a2da0..2d998d4 100644
--- a/sys/dev/syscons/scmouse.c
+++ b/sys/dev/syscons/scmouse.c
@@ -605,8 +605,7 @@ sc_mouse_paste(scr_stat *scp)
#endif /* SC_NO_CUTPASTE */
int
-sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
- struct thread *td)
+sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
mouse_info_t *mouse;
mouse_info_t buf;
@@ -616,7 +615,7 @@ sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
int s;
int f;
- scp = SC_STAT(tp->t_dev);
+ scp = SC_STAT(tp);
switch (cmd) {
diff --git a/sys/dev/syscons/scterm-sc.c b/sys/dev/syscons/scterm-sc.c
index e89debb..b52bea8 100644
--- a/sys/dev/syscons/scterm-sc.c
+++ b/sys/dev/syscons/scterm-sc.c
@@ -705,7 +705,7 @@ outloop:
static int
scterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
- int flag, struct thread *td)
+ struct thread *td)
{
term_stat *tcp = scp->ts;
vid_info_t *vi;
diff --git a/sys/dev/syscons/scvesactl.c b/sys/dev/syscons/scvesactl.c
index c68d46a..9a2c253 100644
--- a/sys/dev/syscons/scvesactl.c
+++ b/sys/dev/syscons/scvesactl.c
@@ -48,19 +48,15 @@ __FBSDID("$FreeBSD$");
#include <dev/fb/fbreg.h>
#include <dev/syscons/syscons.h>
-static d_ioctl_t *prev_user_ioctl;
+static tsw_ioctl_t *prev_user_ioctl;
static int
-vesa_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
+vesa_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
scr_stat *scp;
- struct tty *tp;
int mode;
- tp = dev->si_tty;
- if (!tp)
- return ENXIO;
- scp = SC_STAT(tp->t_dev);
+ scp = SC_STAT(tp);
switch (cmd) {
@@ -123,7 +119,7 @@ vesa_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *
}
if (prev_user_ioctl)
- return (*prev_user_ioctl)(dev, cmd, data, flag, td);
+ return (*prev_user_ioctl)(tp, cmd, data, td);
else
return ENOIOCTL;
}
diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c
index 5e1d910..045f79f 100644
--- a/sys/dev/syscons/scvidctl.c
+++ b/sys/dev/syscons/scvidctl.c
@@ -241,11 +241,8 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
|| tp->t_winsize.ws_row != scp->ysize) {
tp->t_winsize.ws_col = scp->xsize;
tp->t_winsize.ws_row = scp->ysize;
- if (tp->t_pgrp != NULL) {
- PGRP_LOCK(tp->t_pgrp);
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- PGRP_UNLOCK(tp->t_pgrp);
- }
+
+ tty_signal_pgrp(tp, SIGWINCH);
}
return 0;
@@ -308,11 +305,8 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
|| tp->t_winsize.ws_ypixel != scp->ypixel) {
tp->t_winsize.ws_xpixel = scp->xpixel;
tp->t_winsize.ws_ypixel = scp->ypixel;
- if (tp->t_pgrp != NULL) {
- PGRP_LOCK(tp->t_pgrp);
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- PGRP_UNLOCK(tp->t_pgrp);
- }
+
+ tty_signal_pgrp(tp, SIGWINCH);
}
return 0;
@@ -475,7 +469,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
vidd_ioctl((a), (c), (caddr_t)(d)))
int
-sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct thread *td)
+sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
scr_stat *scp;
video_adapter_t *adp;
@@ -488,7 +482,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct thread *
int ival;
#endif
- scp = SC_STAT(tp->t_dev);
+ scp = SC_STAT(tp);
if (scp == NULL) /* tp == SC_MOUSE */
return ENOIOCTL;
adp = scp->sc->adp;
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 96ca0b7..ed5e459 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/random.h>
#include <sys/reboot.h>
+#include <sys/serial.h>
#include <sys/signalvar.h>
#include <sys/sysctl.h>
#include <sys/tty.h>
@@ -69,6 +70,7 @@ __FBSDID("$FreeBSD$");
#include <machine/psl.h>
#include <machine/frame.h>
#endif
+#include <machine/stdarg.h>
#include <dev/kbd/kbdreg.h>
#include <dev/fb/fbreg.h>
@@ -105,7 +107,7 @@ static struct tty *sc_console_tty;
static struct consdev *sc_consptr;
static void *kernel_console_ts;
static scr_stat main_console;
-static struct cdev *main_devs[MAXCONS];
+static struct tty *main_devs[MAXCONS];
static char init_done = COLD;
static char shutdown_in_progress = FALSE;
@@ -150,7 +152,7 @@ SYSCTL_INT(_hw_syscons, OID_AUTO, kbd_debug, CTLFLAG_RW|CTLFLAG_SECURE, &enable_
#include "font.h"
#endif
- d_ioctl_t *sc_user_ioctl;
+ tsw_ioctl_t *sc_user_ioctl;
static bios_values_t bios_value;
@@ -161,24 +163,18 @@ SYSCTL_INT(_machdep, OID_AUTO, enable_panic_key, CTLFLAG_RW, &enable_panic_key,
#define SC_CONSOLECTL 255
#define VTY_WCHAN(sc, vty) (&SC_DEV(sc, vty))
-#define VIRTUAL_TTY(sc, x) (SC_DEV((sc), (x)) != NULL ? \
- SC_DEV((sc), (x))->si_tty : NULL)
-#define ISTTYOPEN(tp) ((tp) && ((tp)->t_state & TS_ISOPEN))
static int debugger;
/* prototypes */
static int sc_allocate_keyboard(sc_softc_t *sc, int unit);
-static struct tty *sc_alloc_tty(struct cdev *dev);
static int scvidprobe(int unit, int flags, int cons);
static int sckbdprobe(int unit, int flags, int cons);
static void scmeminit(void *arg);
-static int scdevtounit(struct cdev *dev);
+static int scdevtounit(struct tty *tp);
static kbd_callback_func_t sckbdevent;
-static int scparam(struct tty *tp, struct termios *t);
-static void scstart(struct tty *tp);
static void scinit(int unit, int flags);
-static scr_stat *sc_get_stat(struct cdev *devptr);
+static scr_stat *sc_get_stat(struct tty *tp);
static void scterm(int unit, int flags);
static void scshutdown(void *arg, int howto);
static u_int scgetc(sc_softc_t *sc, u_int flags);
@@ -219,6 +215,7 @@ static int save_kbd_state(scr_stat *scp);
static int update_kbd_state(scr_stat *scp, int state, int mask);
static int update_kbd_leds(scr_stat *scp, int which);
static timeout_t blink_screen;
+static struct tty *sc_alloc_tty(int, const char *, ...) __printflike(2, 3);
static cn_probe_t sc_cnprobe;
static cn_init_t sc_cninit;
@@ -228,21 +225,23 @@ static cn_putc_t sc_cnputc;
CONSOLE_DRIVER(sc);
-static d_open_t scopen;
-static d_close_t scclose;
-static d_read_t scread;
-static d_ioctl_t scioctl;
-static d_mmap_t scmmap;
-
-static struct cdevsw sc_cdevsw = {
- .d_version = D_VERSION,
- .d_open = scopen,
- .d_close = scclose,
- .d_read = scread,
- .d_ioctl = scioctl,
- .d_mmap = scmmap,
- .d_name = "sc",
- .d_flags = D_TTY | D_NEEDGIANT,
+static tsw_open_t sctty_open;
+static tsw_close_t sctty_close;
+static tsw_outwakeup_t sctty_outwakeup;
+static tsw_ioctl_t sctty_ioctl;
+static tsw_mmap_t sctty_mmap;
+
+static struct ttydevsw sc_ttydevsw = {
+ /*
+ * XXX: we should use the prefix, but this doesn't work for
+ * consolectl.
+ */
+ .tsw_flags = TF_NOPREFIX,
+ .tsw_open = sctty_open,
+ .tsw_close = sctty_close,
+ .tsw_outwakeup = sctty_outwakeup,
+ .tsw_ioctl = sctty_ioctl,
+ .tsw_mmap = sctty_mmap,
};
int
@@ -310,17 +309,47 @@ static char
return names[i].name[(adp->va_flags & V_ADP_COLOR) ? 0 : 1];
}
+static void
+sctty_outwakeup(struct tty *tp)
+{
+ size_t len;
+ u_char buf[PCBURST];
+ scr_stat *scp = sc_get_stat(tp);
+
+ if (scp->status & SLKED ||
+ (scp == scp->sc->cur_scp && scp->sc->blink_in_progress))
+ return;
+
+ for (;;) {
+ len = ttydisc_getc(tp, buf, sizeof buf);
+ if (len == 0)
+ break;
+ sc_puts(scp, buf, len);
+ }
+}
+
static struct tty *
-sc_alloc_tty(struct cdev *dev)
+sc_alloc_tty(int index, const char *fmt, ...)
{
+ va_list ap;
+ struct sc_ttysoftc *stc;
struct tty *tp;
+ char name[11]; /* "consolectl" */
+
+ va_start(ap, fmt);
+
+ /* Allocate TTY object and softc to store unit number. */
+ stc = malloc(sizeof(struct sc_ttysoftc), M_DEVBUF, M_WAITOK);
+ stc->st_index = index;
+ stc->st_stat = NULL;
+ tp = tty_alloc(&sc_ttydevsw, stc, &Giant);
+
+ /* Create device node. */
+ va_start(ap, fmt);
+ vsnrprintf(name, sizeof name, 32, fmt, ap);
+ va_end(ap);
+ tty_makedev(tp, NULL, "%s", name);
- tp = dev->si_tty = ttyalloc();
- ttyinitmode(tp, 1, 0);
- tp->t_oproc = scstart;
- tp->t_param = scparam;
- tp->t_stop = nottystop;
- tp->t_dev = dev;
return (tp);
}
@@ -333,7 +362,6 @@ sc_attach_unit(int unit, int flags)
video_info_t info;
#endif
int vc;
- struct cdev *dev;
flags &= ~SC_KERNEL_CONSOLE;
@@ -418,9 +446,7 @@ sc_attach_unit(int unit, int flags)
for (vc = 0; vc < sc->vtys; vc++) {
if (sc->dev[vc] == NULL) {
- sc->dev[vc] = make_dev(&sc_cdevsw, vc + unit * MAXCONS,
- UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc + unit * MAXCONS);
- sc_alloc_tty(sc->dev[vc]);
+ sc->dev[vc] = sc_alloc_tty(vc, "ttyv%r", vc + unit * MAXCONS);
if (vc == 0 && sc->dev == main_devs)
SC_STAT(sc->dev[0]) = &main_console;
}
@@ -431,11 +457,8 @@ sc_attach_unit(int unit, int flags)
*/
}
- dev = make_dev(&sc_cdevsw, SC_CONSOLECTL,
- UID_ROOT, GID_WHEEL, 0600, "consolectl");
- sc_console_tty = sc_alloc_tty(dev);
- ttyconsolemode(sc_console_tty, 0);
- SC_STAT(dev) = sc_console;
+ sc_console_tty = sc_alloc_tty(0, "consolectl");
+ SC_STAT(sc_console_tty) = sc_console;
return 0;
}
@@ -472,9 +495,9 @@ scmeminit(void *arg)
SYSINIT(sc_mem, SI_SUB_KMEM, SI_ORDER_ANY, scmeminit, NULL);
static int
-scdevtounit(struct cdev *dev)
+scdevtounit(struct tty *tp)
{
- int vty = SC_VTY(dev);
+ int vty = SC_VTY(tp);
if (vty == SC_CONSOLECTL)
return ((sc_console != NULL) ? sc_console->sc->unit : -1);
@@ -485,48 +508,37 @@ scdevtounit(struct cdev *dev)
}
static int
-scopen(struct cdev *dev, int flag, int mode, struct thread *td)
+sctty_open(struct tty *tp)
{
- int unit = scdevtounit(dev);
+ int unit = scdevtounit(tp);
sc_softc_t *sc;
- struct tty *tp;
scr_stat *scp;
#ifndef __sparc64__
keyarg_t key;
#endif
- int error;
DPRINTF(5, ("scopen: dev:%s, unit:%d, vty:%d\n",
- devtoname(dev), unit, SC_VTY(dev)));
+ devtoname(tp->t_dev), unit, SC_VTY(tp)));
- tp = dev->si_tty;
sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
if (sc == NULL)
return ENXIO;
- if (!ISTTYOPEN(tp)) {
- tp->t_termios = tp->t_init_in;
+ if (!tty_opened(tp)) {
/* Use the current setting of the <-- key as default VERASE. */
/* If the Delete key is preferable, an stty is necessary */
#ifndef __sparc64__
if (sc->kbd != NULL) {
key.keynum = KEYCODE_BS;
kbdd_ioctl(sc->kbd, GIO_KEYMAPENT, (caddr_t)&key);
- tp->t_cc[VERASE] = key.key.map[0];
+ tp->t_termios.c_cc[VERASE] = key.key.map[0];
}
#endif
- scparam(tp, &tp->t_termios);
- ttyld_modem(tp, 1);
}
- else
- if (tp->t_state & TS_XCLUDE && priv_check(td, PRIV_TTY_EXCLUSIVE))
- return(EBUSY);
- error = ttyld_open(tp, dev);
-
- scp = sc_get_stat(dev);
+ scp = sc_get_stat(tp);
if (scp == NULL) {
- scp = SC_STAT(dev) = alloc_scp(sc, SC_VTY(dev));
+ scp = SC_STAT(tp) = alloc_scp(sc, SC_VTY(tp));
if (ISGRAPHSC(scp))
sc_set_pixel_mode(scp, NULL, COL, ROW, 16, 8);
}
@@ -535,18 +547,17 @@ scopen(struct cdev *dev, int flag, int mode, struct thread *td)
tp->t_winsize.ws_row = scp->ysize;
}
- return error;
+ return (0);
}
-static int
-scclose(struct cdev *dev, int flag, int mode, struct thread *td)
+static void
+sctty_close(struct tty *tp)
{
- struct tty *tp = dev->si_tty;
scr_stat *scp;
int s;
- if (SC_VTY(dev) != SC_CONSOLECTL) {
- scp = sc_get_stat(tp->t_dev);
+ if (SC_VTY(tp) != SC_CONSOLECTL) {
+ scp = sc_get_stat(tp);
/* were we in the middle of the VT switching process? */
DPRINTF(5, ("sc%d: scclose(), ", scp->sc->unit));
s = spltty();
@@ -568,7 +579,7 @@ scclose(struct cdev *dev, int flag, int mode, struct thread *td)
sc_vtb_destroy(&scp->scr);
#endif
sc_free_history_buffer(scp, scp->ysize);
- SC_STAT(dev) = NULL;
+ SC_STAT(tp) = NULL;
free(scp, M_DEVBUF);
}
#else
@@ -581,13 +592,9 @@ scclose(struct cdev *dev, int flag, int mode, struct thread *td)
kbdd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
DPRINTF(5, ("done.\n"));
}
- spltty();
- ttyld_close(tp, flag);
- tty_close(tp);
- spl0();
- return(0);
}
+#if 0 /* XXX mpsafetty: fix screensaver. What about outwakeup? */
static int
scread(struct cdev *dev, struct uio *uio, int flag)
{
@@ -595,19 +602,22 @@ scread(struct cdev *dev, struct uio *uio, int flag)
sc_touch_scrn_saver();
return ttyread(dev, uio, flag);
}
+#endif
static int
sckbdevent(keyboard_t *thiskbd, int event, void *arg)
{
sc_softc_t *sc;
struct tty *cur_tty;
- int c;
+ int c, error = 0;
size_t len;
u_char *cp;
sc = (sc_softc_t *)arg;
/* assert(thiskbd == sc->kbd) */
+ mtx_lock(&Giant);
+
switch (event) {
case KBDIO_KEYINPUT:
break;
@@ -615,9 +625,10 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
sc->kbd = NULL;
sc->keyboard = -1;
kbd_release(thiskbd, (void *)&sc->keyboard);
- return 0;
+ goto done;
default:
- return EINVAL;
+ error = EINVAL;
+ goto done;
}
/*
@@ -627,10 +638,12 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
*/
while ((c = scgetc(sc, SCGETC_NONBLOCK)) != NOKEY) {
- cur_tty = VIRTUAL_TTY(sc, sc->cur_scp->index);
- if (!ISTTYOPEN(cur_tty)) {
+ cur_tty = SC_DEV(sc, sc->cur_scp->index);
+ if (!tty_opened(cur_tty)) {
cur_tty = sc_console_tty;
- if (!ISTTYOPEN(cur_tty))
+ if (cur_tty == NULL)
+ continue;
+ if (!tty_opened(cur_tty))
continue;
}
@@ -639,47 +652,45 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
switch (KEYFLAGS(c)) {
case 0x0000: /* normal key */
- ttyld_rint(cur_tty, KEYCHAR(c));
+ ttydisc_rint(cur_tty, KEYCHAR(c), 0);
break;
case FKEY: /* function key, return string */
cp = kbdd_get_fkeystr(thiskbd, KEYCHAR(c), &len);
if (cp != NULL) {
- while (len-- > 0)
- ttyld_rint(cur_tty, *cp++);
+ if (ttydisc_can_bypass(cur_tty)) {
+ ttydisc_rint_bypass(cur_tty, cp, len);
+ } else {
+ while (len-- > 0)
+ ttydisc_rint(cur_tty, *cp++, 0);
+ }
}
break;
case MKEY: /* meta is active, prepend ESC */
- ttyld_rint(cur_tty, 0x1b);
- ttyld_rint(cur_tty, KEYCHAR(c));
+ ttydisc_rint(cur_tty, 0x1b, 0);
+ ttydisc_rint(cur_tty, KEYCHAR(c), 0);
break;
case BKEY: /* backtab fixed sequence (esc [ Z) */
- ttyld_rint(cur_tty, 0x1b);
- ttyld_rint(cur_tty, '[');
- ttyld_rint(cur_tty, 'Z');
+ ttydisc_rint(cur_tty, 0x1b, 0);
+ ttydisc_rint(cur_tty, '[', 0);
+ ttydisc_rint(cur_tty, 'Z', 0);
break;
}
+
+ ttydisc_rint_done(cur_tty);
}
sc->cur_scp->status |= MOUSE_HIDDEN;
- return 0;
+done:
+ mtx_unlock(&Giant);
+ return (error);
}
static int
-scparam(struct tty *tp, struct termios *t)
-{
- tp->t_ispeed = t->c_ispeed;
- tp->t_ospeed = t->c_ospeed;
- tp->t_cflag = t->c_cflag;
- return 0;
-}
-
-static int
-scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
+sctty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
int error;
int i;
- struct tty *tp;
sc_softc_t *sc;
scr_stat *scp;
int s;
@@ -688,38 +699,36 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
int ival;
#endif
- tp = dev->si_tty;
-
/* If there is a user_ioctl function call that first */
if (sc_user_ioctl) {
- error = (*sc_user_ioctl)(dev, cmd, data, flag, td);
+ error = (*sc_user_ioctl)(tp, cmd, data, td);
if (error != ENOIOCTL)
return error;
}
- error = sc_vid_ioctl(tp, cmd, data, flag, td);
+ error = sc_vid_ioctl(tp, cmd, data, td);
if (error != ENOIOCTL)
return error;
#ifndef SC_NO_HISTORY
- error = sc_hist_ioctl(tp, cmd, data, flag, td);
+ error = sc_hist_ioctl(tp, cmd, data, td);
if (error != ENOIOCTL)
return error;
#endif
#ifndef SC_NO_SYSMOUSE
- error = sc_mouse_ioctl(tp, cmd, data, flag, td);
+ error = sc_mouse_ioctl(tp, cmd, data, td);
if (error != ENOIOCTL)
return error;
#endif
- scp = sc_get_stat(tp->t_dev);
+ scp = sc_get_stat(tp);
/* assert(scp != NULL) */
/* scp is sc_console, if SC_VTY(dev) == SC_CONSOLECTL. */
sc = scp->sc;
if (scp->tsw) {
- error = (*scp->tsw->te_ioctl)(scp, tp, cmd, data, flag, td);
+ error = (*scp->tsw->te_ioctl)(scp, tp, cmd, data, td);
if (error != ENOIOCTL)
return error;
}
@@ -1031,8 +1040,8 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
case VT_OPENQRY: /* return free virtual console */
for (i = sc->first_vty; i < sc->first_vty + sc->vtys; i++) {
- tp = VIRTUAL_TTY(sc, i);
- if (!ISTTYOPEN(tp)) {
+ tp = SC_DEV(sc, i);
+ if (!tty_opened(tp)) {
*(int *)data = i + 1;
return 0;
}
@@ -1053,7 +1062,8 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
splx(s);
if (error)
return error;
- return sc_switch_scr(sc, i);
+ error = sc_switch_scr(sc, i);
+ return (error);
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
@@ -1441,34 +1451,7 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
break;
}
- return (ttyioctl(dev, cmd, data, flag, td));
-}
-
-static void
-scstart(struct tty *tp)
-{
- struct clist *rbp;
- int s, len;
- u_char buf[PCBURST];
- scr_stat *scp = sc_get_stat(tp->t_dev);
-
- if (scp->status & SLKED ||
- (scp == scp->sc->cur_scp && scp->sc->blink_in_progress))
- return;
- s = spltty();
- if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
- tp->t_state |= TS_BUSY;
- rbp = &tp->t_outq;
- while (rbp->c_cc) {
- len = q_to_b(rbp, buf, PCBURST);
- splx(s);
- sc_puts(scp, buf, len);
- s = spltty();
- }
- tp->t_state &= ~TS_BUSY;
- ttwwakeup(tp);
- }
- splx(s);
+ return (ENOIOCTL);
}
static void
@@ -1548,9 +1531,11 @@ sc_cnputc(struct consdev *cd, int c)
scp->status |= CURSOR_ENABLED;
sc_draw_cursor_image(scp);
}
- tp = VIRTUAL_TTY(scp->sc, scp->index);
- if (ISTTYOPEN(tp))
- scstart(tp);
+ tp = SC_DEV(scp->sc, scp->index);
+ tty_lock(tp);
+ if (tty_opened(tp))
+ sctty_outwakeup(tp);
+ tty_unlock(tp);
}
#endif /* !SC_NO_HISTORY */
@@ -2281,9 +2266,9 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
* if the switch mode is VT_AUTO, unless the next vty is the same
* as the current or the current vty has been closed (but showing).
*/
- tp = VIRTUAL_TTY(sc, cur_scp->index);
+ tp = SC_DEV(sc, cur_scp->index);
if ((cur_scp->index != next_scr)
- && ISTTYOPEN(tp)
+ && tty_opened(tp)
&& (cur_scp->smode.mode == VT_AUTO)
&& ISGRAPHSC(cur_scp)) {
splx(s);
@@ -2299,14 +2284,14 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
* console even if it is closed.
*/
if ((sc_console == NULL) || (next_scr != sc_console->index)) {
- tp = VIRTUAL_TTY(sc, next_scr);
- if (!ISTTYOPEN(tp)) {
+ tp = SC_DEV(sc, next_scr);
+ if (!tty_opened(tp)) {
splx(s);
sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION);
DPRINTF(5, ("error 2, requested vty isn't open!\n"));
return EINVAL;
}
- if ((debugger > 0) && (SC_STAT(tp->t_dev)->smode.mode == VT_PROCESS)) {
+ if ((debugger > 0) && (SC_STAT(tp)->smode.mode == VT_PROCESS)) {
splx(s);
DPRINTF(5, ("error 3, requested vty is in the VT_PROCESS mode\n"));
return EINVAL;
@@ -2609,7 +2594,7 @@ void
sc_change_cursor_shape(scr_stat *scp, int flags, int base, int height)
{
sc_softc_t *sc;
- struct cdev *dev;
+ struct tty *tp;
int s;
int i;
@@ -2635,9 +2620,9 @@ sc_change_cursor_shape(scr_stat *scp, int flags, int base, int height)
}
for (i = sc->first_vty; i < sc->first_vty + sc->vtys; ++i) {
- if ((dev = SC_DEV(sc, i)) == NULL)
+ if ((tp = SC_DEV(sc, i)) == NULL)
continue;
- if ((scp = sc_get_stat(dev)) == NULL)
+ if ((scp = sc_get_stat(tp)) == NULL)
continue;
scp->dflt_curs_attr = sc->curs_attr;
change_cursor_shape(scp, CONS_RESET_CURSOR, -1, -1);
@@ -2759,10 +2744,9 @@ scinit(int unit, int flags)
kernel_default.rev_color);
} else {
/* assert(sc_malloc) */
- sc->dev = malloc(sizeof(struct cdev *)*sc->vtys, M_DEVBUF, M_WAITOK|M_ZERO);
- sc->dev[0] = make_dev(&sc_cdevsw, unit * MAXCONS,
- UID_ROOT, GID_WHEEL, 0600, "ttyv%r", unit * MAXCONS);
- sc_alloc_tty(sc->dev[0]);
+ sc->dev = malloc(sizeof(struct tty *)*sc->vtys, M_DEVBUF,
+ M_WAITOK|M_ZERO);
+ sc->dev[0] = sc_alloc_tty(0, "ttyv%r", unit * MAXCONS);
scp = alloc_scp(sc, sc->first_vty);
SC_STAT(sc->dev[0]) = scp;
}
@@ -3287,9 +3271,9 @@ next_code:
scp->status |= CURSOR_ENABLED;
sc_draw_cursor_image(scp);
}
- tp = VIRTUAL_TTY(sc, scp->index);
- if (ISTTYOPEN(tp))
- scstart(tp);
+ tp = SC_DEV(sc, scp->index);
+ if (tty_opened(tp))
+ sctty_outwakeup(tp);
#endif
}
}
@@ -3382,8 +3366,8 @@ next_code:
for (i = (this_scr - sc->first_vty + 1)%sc->vtys;
sc->first_vty + i != this_scr;
i = (i + 1)%sc->vtys) {
- struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i);
- if (ISTTYOPEN(tp)) {
+ struct tty *tp = SC_DEV(sc, sc->first_vty + i);
+ if (tty_opened(tp)) {
sc_switch_scr(scp->sc, sc->first_vty + i);
break;
}
@@ -3395,8 +3379,8 @@ next_code:
for (i = (this_scr - sc->first_vty + sc->vtys - 1)%sc->vtys;
sc->first_vty + i != this_scr;
i = (i + sc->vtys - 1)%sc->vtys) {
- struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i);
- if (ISTTYOPEN(tp)) {
+ struct tty *tp = SC_DEV(sc, sc->first_vty + i);
+ if (tty_opened(tp)) {
sc_switch_scr(scp->sc, sc->first_vty + i);
break;
}
@@ -3425,11 +3409,11 @@ next_code:
}
static int
-scmmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
+sctty_mmap(struct tty *tp, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
{
scr_stat *scp;
- scp = sc_get_stat(dev);
+ scp = sc_get_stat(tp);
if (scp != scp->sc->cur_scp)
return -1;
return vidd_mmap(scp->sc->adp, offset, paddr, nprot);
@@ -3586,12 +3570,13 @@ sc_paste(scr_stat *scp, u_char *p, int count)
struct tty *tp;
u_char *rmap;
- tp = VIRTUAL_TTY(scp->sc, scp->sc->cur_scp->index);
- if (!ISTTYOPEN(tp))
+ tp = SC_DEV(scp->sc, scp->sc->cur_scp->index);
+ if (!tty_opened(tp))
return;
rmap = scp->sc->scr_rmap;
for (; count > 0; --count)
- ttyld_rint(tp, rmap[*p++]);
+ ttydisc_rint(tp, rmap[*p++], 0);
+ ttydisc_rint_done(tp);
}
void
@@ -3626,9 +3611,9 @@ blink_screen(void *arg)
if (ISGRAPHSC(scp) || (scp->sc->blink_in_progress <= 1)) {
scp->sc->blink_in_progress = 0;
mark_all(scp);
- tp = VIRTUAL_TTY(scp->sc, scp->index);
- if (ISTTYOPEN(tp))
- scstart(tp);
+ tp = SC_DEV(scp->sc, scp->index);
+ if (tty_opened(tp))
+ sctty_outwakeup(tp);
if (scp->sc->delayed_next_scr)
sc_switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
}
@@ -3650,11 +3635,11 @@ blink_screen(void *arg)
*/
static scr_stat *
-sc_get_stat(struct cdev *devptr)
+sc_get_stat(struct tty *tp)
{
- if (devptr == NULL)
+ if (tp == NULL)
return (&main_console);
- return (SC_STAT(devptr));
+ return (SC_STAT(tp));
}
/*
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index f17b294..548cec6 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -102,9 +102,9 @@
*/
#define SC_DRIVER_NAME "syscons"
#endif
-#define SC_VTY(dev) minor(dev)
+#define SC_VTY(dev) (((sc_ttysoftc *)tty_softc(tp))->st_index)
#define SC_DEV(sc, vty) ((sc)->dev[(vty) - (sc)->first_vty])
-#define SC_STAT(dev) (*((scr_stat **)&(dev)->si_drv1))
+#define SC_STAT(tp) (*((scr_stat **)&((sc_ttysoftc *)tty_softc(tp))->st_stat))
/* printable chars */
#ifndef PRINTABLE
@@ -220,7 +220,7 @@ typedef struct sc_softc {
int first_vty;
int vtys;
- struct cdev **dev;
+ struct tty **dev;
struct scr_stat *cur_scp;
struct scr_stat *new_scp;
struct scr_stat *old_scp;
@@ -339,6 +339,12 @@ typedef struct scr_stat {
#endif
} scr_stat;
+/* TTY softc. */
+typedef struct sc_ttysoftc {
+ int st_index;
+ scr_stat *st_stat;
+} sc_ttysoftc;
+
#ifndef SC_NORM_ATTR
#define SC_NORM_ATTR (FG_LIGHTGREY | BG_BLACK)
#endif
@@ -364,7 +370,7 @@ typedef int sc_term_init_t(scr_stat *scp, void **tcp, int code);
typedef int sc_term_term_t(scr_stat *scp, void **tcp);
typedef void sc_term_puts_t(scr_stat *scp, u_char *buf, int len);
typedef int sc_term_ioctl_t(scr_stat *scp, struct tty *tp, u_long cmd,
- caddr_t data, int flag, struct thread *td);
+ caddr_t data, struct thread *td);
typedef int sc_term_reset_t(scr_stat *scp, int code);
#define SC_TE_HARD_RESET 0
#define SC_TE_SOFT_RESET 1
@@ -531,8 +537,8 @@ typedef struct {
} while(0)
/* syscons.c */
-extern int (*sc_user_ioctl)(struct cdev *dev, u_long cmd, caddr_t data,
- int flag, struct thread *td);
+extern int (*sc_user_ioctl)(struct tty *tp, u_long cmd, caddr_t data,
+ struct thread *td);
int sc_probe_unit(int unit, int flags);
int sc_attach_unit(int unit, int flags);
@@ -574,7 +580,7 @@ void sc_hist_end(scr_stat *scp);
int sc_hist_up_line(scr_stat *scp);
int sc_hist_down_line(scr_stat *scp);
int sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data,
- int flag, struct thread *td);
+ struct thread *td);
#endif /* SC_NO_HISTORY */
/* scmouse.c */
@@ -599,7 +605,7 @@ void sc_mouse_paste(scr_stat *scp);
#ifndef SC_NO_SYSMOUSE
void sc_mouse_move(scr_stat *scp, int x, int y);
int sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data,
- int flag, struct thread *td);
+ struct thread *td);
#endif /* SC_NO_SYSMOUSE */
/* scvidctl.c */
@@ -609,7 +615,7 @@ int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode,
int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode);
int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize,
int ysize, int fontsize, int font_width);
-int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
+int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data,
struct thread *td);
int sc_render_add(sc_renderer_t *rndr);
diff --git a/sys/dev/syscons/sysmouse.c b/sys/dev/syscons/sysmouse.c
index 35d761b..9d926b8 100644
--- a/sys/dev/syscons/sysmouse.c
+++ b/sys/dev/syscons/sysmouse.c
@@ -32,8 +32,8 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/conf.h>
#include <sys/priv.h>
+#include <sys/serial.h>
#include <sys/tty.h>
#include <sys/kernel.h>
#include <sys/consio.h>
@@ -45,106 +45,24 @@ __FBSDID("$FreeBSD$");
#define SC_MOUSE 128 /* minor number */
-static d_open_t smopen;
-static d_close_t smclose;
-static d_ioctl_t smioctl;
-
-static struct cdevsw sm_cdevsw = {
- .d_version = D_VERSION,
- .d_open = smopen,
- .d_close = smclose,
- .d_ioctl = smioctl,
- .d_name = "sysmouse",
- .d_flags = D_TTY | D_NEEDGIANT,
-};
-
/* local variables */
static struct tty *sysmouse_tty;
static int mouse_level; /* sysmouse protocol level */
static mousestatus_t mouse_status;
-static void smstart(struct tty *tp);
-static int smparam(struct tty *tp, struct termios *t);
-
-static int
-smopen(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct tty *tp;
-
- DPRINTF(5, ("smopen: dev:%s, vty:%d\n",
- devtoname(dev), SC_VTY(dev)));
-
-#if 0
- if (SC_VTY(dev) != SC_MOUSE)
- return ENXIO;
-#endif
-
- tp = dev->si_tty;
- if (!(tp->t_state & TS_ISOPEN)) {
- ttyinitmode(tp, 0, 0);
- smparam(tp, &tp->t_termios);
- ttyld_modem(tp, 1);
- } else if (tp->t_state & TS_XCLUDE &&
- priv_check(td, PRIV_TTY_EXCLUSIVE)) {
- return EBUSY;
- }
-
- return ttyld_open(tp, dev);
-}
-
-static int
-smclose(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct tty *tp;
- int s;
-
- tp = dev->si_tty;
- s = spltty();
- mouse_level = 0;
- ttyld_close(tp, flag);
- tty_close(tp);
- splx(s);
-
- return 0;
-}
-
static void
-smstart(struct tty *tp)
-{
- struct clist *rbp;
- u_char buf[PCBURST];
- int s;
-
- s = spltty();
- if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
- tp->t_state |= TS_BUSY;
- rbp = &tp->t_outq;
- while (rbp->c_cc)
- q_to_b(rbp, buf, PCBURST);
- tp->t_state &= ~TS_BUSY;
- ttwwakeup(tp);
- }
- splx(s);
-}
-
-static int
-smparam(struct tty *tp, struct termios *t)
+smdev_close(struct tty *tp)
{
- tp->t_ispeed = t->c_ispeed;
- tp->t_ospeed = t->c_ospeed;
- tp->t_cflag = t->c_cflag;
- return 0;
+ mouse_level = 0;
}
static int
-smioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
+smdev_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
- struct tty *tp;
mousehw_t *hw;
mousemode_t *mode;
int s;
- tp = dev->si_tty;
switch (cmd) {
case MOUSE_GETHWINFO: /* get device information */
@@ -224,25 +142,35 @@ smioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
return ENODEV;
}
- return(ttyioctl(dev, cmd, data, flag, td));
+ return (ENOIOCTL);
}
+static int
+smdev_param(struct tty *tp, struct termios *t)
+{
+
+ /*
+ * Set the output baud rate to zero. The mouse device supports
+ * no output, so we don't want to waste buffers.
+ */
+ t->c_ispeed = TTYDEF_SPEED_PSEUDO;
+ t->c_ospeed = B0;
+
+ return (0);
+}
+
+static struct ttydevsw smdev_ttydevsw = {
+ .tsw_flags = TF_NOPREFIX,
+ .tsw_close = smdev_close,
+ .tsw_ioctl = smdev_ioctl,
+ .tsw_param = smdev_param,
+};
+
static void
sm_attach_mouse(void *unused)
{
- struct cdev *dev;
- struct tty *tp;
-
- dev = make_dev(&sm_cdevsw, SC_MOUSE, UID_ROOT, GID_WHEEL, 0600,
- "sysmouse");
- dev->si_tty = tp = ttyalloc();
- tp->t_oproc = smstart;
- tp->t_param = smparam;
- tp->t_stop = nottystop;
- tp->t_dev = dev;
-
- sysmouse_tty = tp;
- /* sysmouse doesn't have scr_stat */
+ sysmouse_tty = tty_alloc(&smdev_ttydevsw, NULL, &Giant);
+ tty_makedev(sysmouse_tty, NULL, "sysmouse");
}
SYSINIT(sysmouse, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sm_attach_mouse, NULL);
@@ -293,7 +221,7 @@ sysmouse_event(mouse_info_t *info)
if (mouse_status.flags == 0)
return 0;
- if ((sysmouse_tty == NULL) || !(sysmouse_tty->t_state & TS_ISOPEN))
+ if ((sysmouse_tty == NULL) || !tty_opened(sysmouse_tty))
return mouse_status.flags;
/* the first five bytes are compatible with MouseSystems' */
@@ -306,7 +234,7 @@ sysmouse_event(mouse_info_t *info)
buf[2] = y >> 1;
buf[4] = y - buf[2];
for (i = 0; i < MOUSE_MSC_PACKETSIZE; ++i)
- ttyld_rint(sysmouse_tty, buf[i]);
+ ttydisc_rint(sysmouse_tty, buf[i], 0);
if (mouse_level >= 1) {
/* extended part */
z = imax(imin(z, 127), -128);
@@ -315,8 +243,9 @@ sysmouse_event(mouse_info_t *info)
/* buttons 4-10 */
buf[7] = (~mouse_status.button >> 3) & 0x7f;
for (i = MOUSE_MSC_PACKETSIZE; i < MOUSE_SYS_PACKETSIZE; ++i)
- ttyld_rint(sysmouse_tty, buf[i]);
+ ttydisc_rint(sysmouse_tty, buf[i], 0);
}
+ ttydisc_rint_done(sysmouse_tty);
return mouse_status.flags;
}
OpenPOWER on IntegriCloud