From owner-svn-src-all@FreeBSD.ORG Sun Jan 27 23:33:43 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 5107098D; Sun, 27 Jan 2013 23:33:43 +0000 (UTC) (envelope-from cperciva@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 37C84C25; Sun, 27 Jan 2013 23:33:43 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r0RNXhra031357; Sun, 27 Jan 2013 23:33:43 GMT (envelope-from cperciva@svn.freebsd.org) Received: (from cperciva@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r0RNXhuO031356; Sun, 27 Jan 2013 23:33:43 GMT (envelope-from cperciva@svn.freebsd.org) Message-Id: <201301272333.r0RNXhuO031356@svn.freebsd.org> From: Colin Percival Date: Sun, 27 Jan 2013 23:33:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r246016 - head/sys/dev/uart X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Jan 2013 23:33:43 -0000 Author: cperciva Date: Sun Jan 27 23:33:42 2013 New Revision: 246016 URL: http://svnweb.freebsd.org/changeset/base/246016 Log: Add a loader tunable "hw.broken_txfifo" which enables a workaround for a bug in old versions of QEMU (and Xen, and other places using QEMU code). On those buggy emulated UARTs, the "TX idle" interrupt gets lost; with this workaround, we spinwait for the TX to happen and then send ourselves the interrupt. It's ugly but it works, while minimizing the impact on the code for the !broken_txfifo case. MFC after: 2 weeks Modified: head/sys/dev/uart/uart_dev_ns8250.c Modified: head/sys/dev/uart/uart_dev_ns8250.c ============================================================================== --- head/sys/dev/uart/uart_dev_ns8250.c Sun Jan 27 23:21:51 2013 (r246015) +++ head/sys/dev/uart/uart_dev_ns8250.c Sun Jan 27 23:33:42 2013 (r246016) @@ -31,6 +31,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -845,6 +847,11 @@ ns8250_bus_setsig(struct uart_softc *sc, return (0); } +static int broken_txfifo = 0; +SYSCTL_INT(_hw, OID_AUTO, broken_txfifo, CTLFLAG_RW | CTLFLAG_TUN, + &broken_txfifo, 0, "UART FIFO has QEMU emulation bug"); +TUNABLE_INT("hw.broken_txfifo", &broken_txfifo); + static int ns8250_bus_transmit(struct uart_softc *sc) { @@ -862,7 +869,12 @@ ns8250_bus_transmit(struct uart_softc *s uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); uart_barrier(bas); } - sc->sc_txbusy = 1; + if (broken_txfifo) + ns8250_drain(bas, UART_DRAIN_TRANSMITTER); + else + sc->sc_txbusy = 1; uart_unlock(sc->sc_hwmtx); + if (broken_txfifo) + uart_sched_softih(sc, SER_INT_TXIDLE); return (0); }