summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/vmd/ns8250.c40
-rw-r--r--usr.sbin/vmd/vmd.c13
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)