diff options
-rw-r--r-- | usr.sbin/vmd/ns8250.c | 40 | ||||
-rw-r--r-- | usr.sbin/vmd/vmd.c | 13 |
2 files changed, 45 insertions, 8 deletions
diff --git a/usr.sbin/vmd/ns8250.c b/usr.sbin/vmd/ns8250.c index 259d3f64a49..0e956159f5c 100644 --- a/usr.sbin/vmd/ns8250.c +++ b/usr.sbin/vmd/ns8250.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ns8250.c,v 1.12 2017/09/15 02:35:39 mlarkin Exp $ */ +/* $OpenBSD: ns8250.c,v 1.13 2018/01/08 11:58:27 mpi Exp $ */ /* * Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org> * @@ -16,6 +16,7 @@ */ #include <sys/types.h> +#include <sys/ttycom.h> #include <dev/ic/comreg.h> @@ -133,6 +134,30 @@ com_rcv_event(int fd, short kind, void *arg) } /* + * com_rcv_handle_break + * + * Set/clear break detected contidion based on received TIOCUCNTL_{S,C}BRK. + */ +static int +com_rcv_handle_break(struct ns8250_dev *com, uint8_t cmd) +{ + switch (cmd) { + case 0: /* DATA */ + return 0; + case TIOCUCNTL_SBRK: + com->regs.lsr |= LSR_BI; + break; + case TIOCUCNTL_CBRK: + com->regs.lsr &= ~LSR_BI; + break; + default: + log_warnx("unexpected UCNTL ioctl: %d", cmd); + } + + return 1; +} + +/* * com_rcv * * Move received byte into com data register. @@ -141,7 +166,7 @@ com_rcv_event(int fd, short kind, void *arg) static void com_rcv(struct ns8250_dev *com, uint32_t vm_id, uint32_t vcpu_id) { - char ch; + char buf[2]; ssize_t sz; /* @@ -149,7 +174,7 @@ com_rcv(struct ns8250_dev *com, uint32_t vm_id, uint32_t vcpu_id) * If so, consume the character, buffer it into the com1 data register * assert IRQ4, and set the line status register RXRDY bit. */ - sz = read(com->fd, &ch, sizeof(char)); + sz = read(com->fd, buf, sizeof(buf)); if (sz == -1) { /* * If we get EAGAIN, we'll retry and get the character later. @@ -158,11 +183,14 @@ com_rcv(struct ns8250_dev *com, uint32_t vm_id, uint32_t vcpu_id) */ if (errno != EAGAIN) log_warn("unexpected read error on com device"); - } else if (sz != 1) - log_warnx("unexpected read return value on com device"); + } else if (sz != 1 && sz != 2) + log_warnx("unexpected read return value %zd on com device", sz); else { + if (com_rcv_handle_break(com, buf[0])) + buf[1] = 0; + com->regs.lsr |= LSR_RXRDY; - com->regs.data = ch; + com->regs.data = buf[1]; if (com->regs.ier & IER_ERXRDY) { com->regs.iir |= IIR_RXRDY; diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c index f0ca84709d2..450e8f8babd 100644 --- a/usr.sbin/vmd/vmd.c +++ b/usr.sbin/vmd/vmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.c,v 1.77 2018/01/03 05:39:56 ccardenas Exp $ */ +/* $OpenBSD: vmd.c,v 1.78 2018/01/08 11:58:27 mpi Exp $ */ /* * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> @@ -22,6 +22,7 @@ #include <sys/cdefs.h> #include <sys/stat.h> #include <sys/tty.h> +#include <sys/ttycom.h> #include <sys/ioctl.h> #include <stdio.h> @@ -800,7 +801,7 @@ vmd_configure(void) * stdio - for malloc and basic I/O including events. * rpath - for reload to open and read the configuration files. * wpath - for opening disk images and tap devices. - * tty - for openpty. + * tty - for openpty and TIOCUCNTL. * proc - run kill to terminate its children safely. * sendfd - for disks, interfaces and other fds. * recvfd - for send and receive. @@ -1273,6 +1274,7 @@ vm_opentty(struct vmd_vm *vm) uid_t uid; gid_t gid; mode_t mode; + int on; /* * Open tty with pre-opened PTM fd @@ -1280,6 +1282,13 @@ vm_opentty(struct vmd_vm *vm) if ((ioctl(env->vmd_ptmfd, PTMGET, &ptm) == -1)) return (-1); + /* + * We use user ioctl(2) mode to pass break commands. + */ + on = 1; + if (ioctl(ptm.cfd, TIOCUCNTL, &on)) + fatal("could not enable user ioctl mode"); + vm->vm_tty = ptm.cfd; close(ptm.sfd); if ((vm->vm_ttyname = strdup(ptm.sn)) == NULL) |