From 0077bcdf4243c5c43b9eb460ead1664bc507ea53 Mon Sep 17 00:00:00 2001 From: mpi Date: Mon, 8 Jan 2018 11:58:27 +0000 Subject: [PATCH] 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@ --- usr.sbin/vmd/ns8250.c | 40 ++++++++++++++++++++++++++++++++++------ 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 * @@ -16,6 +16,7 @@ */ #include +#include #include @@ -132,6 +133,30 @@ com_rcv_event(int fd, short kind, void *arg) mutex_unlock(&com1_dev.mutex); } +/* + * 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 * @@ -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 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -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) -- 2.20.1