summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2018-01-08 11:58:28 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2018-01-08 11:58:28 +0000
commite72afbd2679e83a8e00bf7d8ddcfd957b588d816 (patch)
tree13d675efc46b0be440088a66e02fce7e3b26acaa
parentf0909d36eaaf373fb38f3831a2ec42032bea8d7a (diff)
Enable TIOCUCNTL to be able to set ns8250's break detected condition.
It is now possible to send BREAK commands to vmd(8) independently of the serial terminal emulator. Happy virtual ddb(4) hacking! No objection from mlarkin@, ok nicm@, ccardenas@, deraadt@
-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)