summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyve
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2015-07-06 19:33:29 +0000
committerneel <neel@FreeBSD.org>2015-07-06 19:33:29 +0000
commit0a74489e333d800a5083c31a38dd5529359c31dc (patch)
tree26984e224ef95e30b77d170a01c1c0d513b1a2f0 /usr.sbin/bhyve
parentabd8f81b9252eb125122ca26944c20b3567f3460 (diff)
downloadFreeBSD-src-0a74489e333d800a5083c31a38dd5529359c31dc.zip
FreeBSD-src-0a74489e333d800a5083c31a38dd5529359c31dc.tar.gz
Always assert DCD and DSR in bhyve's uart emulation.
The /etc/ttys entry for a serial console in FreeBSD/x86 is as follows: ttyu0 "/usr/libexec/getty 3wire" vt100 onifconsole secure The initial terminal type passed to getty(8) is "3wire" which sets the CLOCAL flag. However reset(1) clears this flag and any programs that try to open the terminal will hang waiting for DCD to be asserted. Fix this by always asserting DCD and DSR in the emulated uart. The following discussion on virtualization@ has more details: https://lists.freebsd.org/pipermail/freebsd-virtualization/2015-June/003666.html Reported by: jmg Discussed with: grehan
Diffstat (limited to 'usr.sbin/bhyve')
-rw-r--r--usr.sbin/bhyve/uart_emul.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/usr.sbin/bhyve/uart_emul.c b/usr.sbin/bhyve/uart_emul.c
index 4242e5c..538bf58 100644
--- a/usr.sbin/bhyve/uart_emul.c
+++ b/usr.sbin/bhyve/uart_emul.c
@@ -272,6 +272,37 @@ uart_opentty(struct uart_softc *sc)
assert(sc->mev != NULL);
}
+static uint8_t
+modem_status(uint8_t mcr)
+{
+ uint8_t msr;
+
+ if (mcr & MCR_LOOPBACK) {
+ /*
+ * In the loopback mode certain bits from the MCR are
+ * reflected back into MSR.
+ */
+ msr = 0;
+ if (mcr & MCR_RTS)
+ msr |= MSR_CTS;
+ if (mcr & MCR_DTR)
+ msr |= MSR_DSR;
+ if (mcr & MCR_OUT1)
+ msr |= MSR_RI;
+ if (mcr & MCR_OUT2)
+ msr |= MSR_DCD;
+ } else {
+ /*
+ * Always assert DCD and DSR so tty open doesn't block
+ * even if CLOCAL is turned off.
+ */
+ msr = MSR_DCD | MSR_DSR;
+ }
+ assert((msr & MSR_DELTA_MASK) == 0);
+
+ return (msr);
+}
+
/*
* The IIR returns a prioritized interrupt reason:
* - receive data available
@@ -304,6 +335,7 @@ uart_reset(struct uart_softc *sc)
divisor = DEFAULT_RCLK / DEFAULT_BAUD / 16;
sc->dll = divisor;
sc->dlh = divisor >> 16;
+ sc->msr = modem_status(sc->mcr);
rxfifo_reset(sc, 1); /* no fifo until enabled by software */
}
@@ -363,7 +395,7 @@ uart_write(struct uart_softc *sc, int offset, uint8_t value)
uint8_t msr;
pthread_mutex_lock(&sc->mtx);
-
+
/*
* Take care of the special case DLAB accesses first
*/
@@ -426,22 +458,7 @@ uart_write(struct uart_softc *sc, int offset, uint8_t value)
case REG_MCR:
/* Apply mask so that bits 5-7 are 0 */
sc->mcr = value & 0x1F;
-
- msr = 0;
- if (sc->mcr & MCR_LOOPBACK) {
- /*
- * In the loopback mode certain bits from the
- * MCR are reflected back into MSR
- */
- if (sc->mcr & MCR_RTS)
- msr |= MSR_CTS;
- if (sc->mcr & MCR_DTR)
- msr |= MSR_DSR;
- if (sc->mcr & MCR_OUT1)
- msr |= MSR_RI;
- if (sc->mcr & MCR_OUT2)
- msr |= MSR_DCD;
- }
+ msr = modem_status(sc->mcr);
/*
* Detect if there has been any change between the
OpenPOWER on IntegriCloud