From owner-svn-src-all@freebsd.org Sun Aug 23 17:07:25 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CB45F9C0D19; Sun, 23 Aug 2015 17:07:25 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BA78F1BBA; Sun, 23 Aug 2015 17:07:25 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t7NH7PXa013402; Sun, 23 Aug 2015 17:07:25 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t7NH7O5W013396; Sun, 23 Aug 2015 17:07:24 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201508231707.t7NH7O5W013396@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Sun, 23 Aug 2015 17:07:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r287037 - in stable/10: . share/man/man4 sys/dev/uart X-SVN-Group: stable-10 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.20 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, 23 Aug 2015 17:07:25 -0000 Author: ian Date: Sun Aug 23 17:07:23 2015 New Revision: 287037 URL: https://svnweb.freebsd.org/changeset/base/287037 Log: MFC r286469, r286591, r286595, r286596, r286613: Provide the tty-layer mutex when initializing the pps api. This allows time_pps_fetch() to be used in blocking mode. Allow the choice of PPS signal captured by uart(4) to be runtime-configured, eliminating the need to build a custom kernel to use the CTS signal. Correct the polarity of the PPS assert and clear events with respect to the electrical signals on the serial port. Document the change in polarity of the uart(4) PPS capture. Style fix -- do the braces for switches correctly. Relnotes: yes Modified: stable/10/UPDATING stable/10/share/man/man4/uart.4 stable/10/sys/dev/uart/uart_bus.h stable/10/sys/dev/uart/uart_core.c stable/10/sys/dev/uart/uart_tty.c Directory Properties: stable/10/ (props changed) Modified: stable/10/UPDATING ============================================================================== --- stable/10/UPDATING Sun Aug 23 16:22:21 2015 (r287036) +++ stable/10/UPDATING Sun Aug 23 17:07:23 2015 (r287037) @@ -16,6 +16,20 @@ from older versions of FreeBSD, try WITH stable/10, and then rebuild without this option. The bootstrap process from older version of current is a bit fragile. +20150823: + The polarity of Pulse Per Second (PPS) capture events with the + uart(4) driver has been corrected. Prior to this change the PPS + "assert" event corresponded to the trailing edge of a positive PPS + pulse and the "clear" event was the leading edge of the next pulse. + + As the width of a PPS pulse in a typical GPS receiver is on the + order of 1 millisecond, most users will not notice any significant + difference with this change. + + Anyone who has compensated for the historical polarity reversal by + configuring a negative offset equal to the pulse width will need to + remove that workaround. + 20150822: From legacy ata(4) driver was removed support for SATA controllers supported by more functional drivers ahci(4), siis(4) and mvs(4). Modified: stable/10/share/man/man4/uart.4 ============================================================================== --- stable/10/share/man/man4/uart.4 Sun Aug 23 16:22:21 2015 (r287036) +++ stable/10/share/man/man4/uart.4 Sun Aug 23 17:07:23 2015 (r287037) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 12, 2008 +.Dd August 10, 2015 .Dt UART 4 .Os .Sh NAME @@ -151,6 +151,39 @@ SCC: serial communications controllers s device driver. .El .\" +.Sh Pulse Per Second (PPS) Timing Interface +The +.Nm +driver can capture PPS timing information as defined in RFC 2783. +The API, accessed via +.Xr ioctl 8 , +is available on the tty device. +To use the PPS capture feature with +.Xr ntpd 8 , +symlink the tty device to +.Va /dev/pps0. +.Pp +The +.Va hw.uart.pps_mode +tunable configures the PPS capture mode for all uart devices; +it can be set in +.Xr loader.conf 5 . +The +.Va dev.uart.0.pps_mode +sysctl configures the PPS capture mode for a specific uart device; +it can be set in +.Xr loader.conf 5 +or +.Xr sysctl.conf 5 . +The following capture modes are available: +.Bl -tag -compact -offset "mmmm" -width "mmmm" +.It 0 +Capture disabled. +.It 1 +Capture pulses on the CTS line. +.It 2 +Capture pulses on the DCD line (default). +.El .Sh FILES .Bl -tag -width ".Pa /dev/ttyu?.init" -compact .It Pa /dev/ttyu? Modified: stable/10/sys/dev/uart/uart_bus.h ============================================================================== --- stable/10/sys/dev/uart/uart_bus.h Sun Aug 23 16:22:21 2015 (r287036) +++ stable/10/sys/dev/uart/uart_bus.h Sun Aug 23 17:07:23 2015 (r287037) @@ -48,14 +48,6 @@ #define UART_STAT_OVERRUN 0x0400 #define UART_STAT_PARERR 0x0800 -#ifdef UART_PPS_ON_CTS -#define UART_SIG_DPPS SER_DCTS -#define UART_SIG_PPS SER_CTS -#else -#define UART_SIG_DPPS SER_DDCD -#define UART_SIG_PPS SER_DCD -#endif - /* UART_IOCTL() requests */ #define UART_IOCTL_BREAK 1 #define UART_IOCTL_IFLOW 2 @@ -119,6 +111,7 @@ struct uart_softc { /* Pulse capturing support (PPS). */ struct pps_state sc_pps; + int sc_pps_mode; /* Upper layer data. */ void *sc_softih; @@ -149,6 +142,7 @@ void uart_sched_softih(struct uart_softc int uart_tty_attach(struct uart_softc *); int uart_tty_detach(struct uart_softc *); +struct mtx *uart_tty_getlock(struct uart_softc *); void uart_tty_intr(void *arg); /* Modified: stable/10/sys/dev/uart/uart_core.c ============================================================================== --- stable/10/sys/dev/uart/uart_core.c Sun Aug 23 16:22:21 2015 (r287036) +++ stable/10/sys/dev/uart/uart_core.c Sun Aug 23 17:07:23 2015 (r287037) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -64,6 +65,108 @@ static MALLOC_DEFINE(M_UART, "UART", "UA static int uart_poll_freq = UART_POLL_FREQ; TUNABLE_INT("debug.uart_poll_freq", &uart_poll_freq); +#define PPS_MODE_DISABLED 0 +#define PPS_MODE_CTS 1 +#define PPS_MODE_DCD 2 + +static inline int +uart_pps_signal(int pps_mode) +{ + + switch(pps_mode) { + case PPS_MODE_CTS: + return (SER_CTS); + case PPS_MODE_DCD: + return (SER_DCD); + } + return (0); +} +static inline int +uart_pps_mode_valid(int pps_mode) +{ + + switch(pps_mode) { + case PPS_MODE_DISABLED: + case PPS_MODE_CTS: + case PPS_MODE_DCD: + return (true); + } + return (false); +} + +static const char * +uart_pps_mode_name(int pps_mode) +{ + switch(pps_mode) { + case PPS_MODE_DISABLED: + return ("disabled"); + case PPS_MODE_CTS: + return ("CTS"); + case PPS_MODE_DCD: + return ("DCD"); + } + return ("invalid"); +} + +static int +uart_pps_mode_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct uart_softc *sc; + int err, tmp; + + sc = arg1; + tmp = sc->sc_pps_mode; + err = sysctl_handle_int(oidp, &tmp, 0, req); + if (err != 0 || req->newptr == NULL) + return (err); + if (!uart_pps_mode_valid(tmp)) + return (EINVAL); + sc->sc_pps_mode = tmp; + return(0); +} + +static void +uart_pps_init(struct uart_softc *sc) +{ + struct sysctl_ctx_list *ctx; + struct sysctl_oid *tree; + + ctx = device_get_sysctl_ctx(sc->sc_dev); + tree = device_get_sysctl_tree(sc->sc_dev); + + /* + * The historical default for pps capture mode is either DCD or CTS, + * depending on the UART_PPS_ON_CTS kernel option. Start with that, + * then try to fetch the tunable that overrides the mode for all uart + * devices, then try to fetch the sysctl-tunable that overrides the mode + * for one specific device. + */ +#ifdef UART_PPS_ON_CTS + sc->sc_pps_mode = PPS_MODE_CTS; +#else + sc->sc_pps_mode = PPS_MODE_DCD; +#endif + TUNABLE_INT_FETCH("hw.uart.pps_mode", &sc->sc_pps_mode); + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "pps_mode", + CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0, uart_pps_mode_sysctl, "I", + "pulse capturing mode - 0/1/2 - disabled/CTS/DCD"); + + if (!uart_pps_mode_valid(sc->sc_pps_mode)) { + device_printf(sc->sc_dev, + "Invalid pps_mode %d configured; disabling PPS capture\n", + sc->sc_pps_mode); + sc->sc_pps_mode = PPS_MODE_DISABLED; + } else if (bootverbose) { + device_printf(sc->sc_dev, "PPS capture mode %d (%s)\n", + sc->sc_pps_mode, uart_pps_mode_name(sc->sc_pps_mode)); + } + + sc->sc_pps.ppscap = PPS_CAPTUREBOTH; + sc->sc_pps.driver_mtx = uart_tty_getlock(sc); + sc->sc_pps.driver_abi = PPS_ABI_VERSION; + pps_init_abi(&sc->sc_pps); +} + void uart_add_sysdev(struct uart_devinfo *di) { @@ -199,15 +302,22 @@ static __inline int uart_intr_sigchg(void *arg) { struct uart_softc *sc = arg; - int new, old, sig; + int new, old, pps_sig, sig; sig = UART_GETSIG(sc); + /* + * Time pulse counting support. Note that both CTS and DCD are + * active-low signals. The status bit is high to indicate that + * the signal on the line is low, which corresponds to a PPS + * clear event. + */ if (sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) { - if (sig & UART_SIG_DPPS) { + pps_sig = uart_pps_signal(sc->sc_pps_mode); + if (sig & SER_DELTA(pps_sig)) { pps_capture(&sc->sc_pps); - pps_event(&sc->sc_pps, (sig & UART_SIG_PPS) ? - PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); + pps_event(&sc->sc_pps, (sig & pps_sig) ? + PPS_CAPTURECLEAR : PPS_CAPTUREASSERT); } } @@ -499,9 +609,6 @@ uart_bus_attach(device_t dev) sc->sc_sysdev->stopbits); } - sc->sc_pps.ppscap = PPS_CAPTUREBOTH; - pps_init(&sc->sc_pps); - sc->sc_leaving = 0; sc->sc_testintr = 1; filt = uart_intr(sc); @@ -554,10 +661,14 @@ uart_bus_attach(device_t dev) printf("\n"); } - error = (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL) - ? (*sc->sc_sysdev->attach)(sc) : uart_tty_attach(sc); - if (error) - goto fail; + if (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL) { + if ((error = sc->sc_sysdev->attach(sc)) != 0) + goto fail; + } else { + if ((error = uart_tty_attach(sc)) != 0) + goto fail; + uart_pps_init(sc); + } if (sc->sc_sysdev != NULL) sc->sc_sysdev->hwmtx = sc->sc_hwmtx; Modified: stable/10/sys/dev/uart/uart_tty.c ============================================================================== --- stable/10/sys/dev/uart/uart_tty.c Sun Aug 23 16:22:21 2015 (r287036) +++ stable/10/sys/dev/uart/uart_tty.c Sun Aug 23 17:07:23 2015 (r287037) @@ -410,3 +410,13 @@ uart_tty_detach(struct uart_softc *sc) return (0); } + +struct mtx * +uart_tty_getlock(struct uart_softc *sc) +{ + + if (sc->sc_u.u_tty.tp != NULL) + return (tty_getlock(sc->sc_u.u_tty.tp)); + else + return (NULL); +}