From owner-svn-src-stable@FreeBSD.ORG Sun May 24 00:53:45 2015 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 61B095AE; Sun, 24 May 2015 00:53:45 +0000 (UTC) Received: from svn.freebsd.org (svn.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 4F9C8139E; Sun, 24 May 2015 00:53:45 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t4O0rjDa013443; Sun, 24 May 2015 00:53:45 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t4O0rhpe013434; Sun, 24 May 2015 00:53:43 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201505240053.t4O0rhpe013434@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Sun, 24 May 2015 00:53:43 +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: r283341 - in stable/10/sys: dev/usb/serial kern sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 May 2015 00:53:45 -0000 Author: ian Date: Sun May 24 00:53:43 2015 New Revision: 283341 URL: https://svnweb.freebsd.org/changeset/base/283341 Log: MFC r279728, r279729, r279756, r279773, r282424, r281367: Add mutex support to the pps_ioctl() API in the kernel. Add PPS support to USB serial drivers. Use correct mode variable for PPS support. Switch polarity of USB serial PPS events. The ftdi "get latency" and "get bitmode" device commands are read operations, not writes. Implement a mechanism for making changes in the kernel<->driver PPS interface without breaking ABI or API compatibility with existing drivers. Bump version number to indicate the new PPS ABI version changes in the pps_state structure. Modified: stable/10/sys/dev/usb/serial/uftdi.c stable/10/sys/dev/usb/serial/usb_serial.c stable/10/sys/dev/usb/serial/usb_serial.h stable/10/sys/kern/kern_tc.c stable/10/sys/sys/param.h stable/10/sys/sys/timepps.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/usb/serial/uftdi.c ============================================================================== --- stable/10/sys/dev/usb/serial/uftdi.c Sat May 23 23:35:19 2015 (r283340) +++ stable/10/sys/dev/usb/serial/uftdi.c Sun May 24 00:53:43 2015 (r283341) @@ -1703,7 +1703,7 @@ uftdi_get_bitmode(struct ucom_softc *uco struct uftdi_softc *sc = ucom->sc_parent; usb_device_request_t req; - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = FTDI_SIO_GET_BITMODE; USETW(req.wIndex, sc->sc_ucom.sc_portno); @@ -1740,7 +1740,7 @@ uftdi_get_latency(struct ucom_softc *uco usb_error_t err; uint8_t buf; - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = FTDI_SIO_GET_LATENCY; USETW(req.wIndex, sc->sc_ucom.sc_portno); Modified: stable/10/sys/dev/usb/serial/usb_serial.c ============================================================================== --- stable/10/sys/dev/usb/serial/usb_serial.c Sat May 23 23:35:19 2015 (r283340) +++ stable/10/sys/dev/usb/serial/usb_serial.c Sun May 24 00:53:43 2015 (r283341) @@ -96,6 +96,11 @@ __FBSDID("$FreeBSD$"); static SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom"); +static int ucom_pps_mode; + +SYSCTL_INT(_hw_usb_ucom, OID_AUTO, pps_mode, CTLFLAG_RWTUN, + &ucom_pps_mode, 0, "pulse capturing mode - 0/1/2 - disabled/CTS/DCD"); + #ifdef USB_DEBUG static int ucom_debug = 0; @@ -412,6 +417,11 @@ ucom_attach_tty(struct ucom_super_softc sc->sc_tty = tp; + sc->sc_pps.ppscap = PPS_CAPTUREBOTH; + sc->sc_pps.driver_abi = PPS_ABI_VERSION; + sc->sc_pps.driver_mtx = sc->sc_mtx; + pps_init_abi(&sc->sc_pps); + DPRINTF("ttycreate: %s\n", buf); /* Check if this device should be a console */ @@ -861,6 +871,8 @@ ucom_ioctl(struct tty *tp, u_long cmd, c } else { error = ENOIOCTL; } + if (error == ENOIOCTL) + error = pps_ioctl(cmd, data, &sc->sc_pps); break; } return (error); @@ -1064,7 +1076,7 @@ ucom_cfg_status_change(struct usb_proc_m struct tty *tp; uint8_t new_msr; uint8_t new_lsr; - uint8_t onoff; + uint8_t msr_delta; uint8_t lsr_delta; tp = sc->sc_tty; @@ -1088,15 +1100,42 @@ ucom_cfg_status_change(struct usb_proc_m /* TTY device closed */ return; } - onoff = ((sc->sc_msr ^ new_msr) & SER_DCD); + msr_delta = (sc->sc_msr ^ new_msr); lsr_delta = (sc->sc_lsr ^ new_lsr); sc->sc_msr = new_msr; sc->sc_lsr = new_lsr; - if (onoff) { + /* + * 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. + */ + switch(ucom_pps_mode) { + case 1: + if ((sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) && + (msr_delta & SER_CTS)) { + pps_capture(&sc->sc_pps); + pps_event(&sc->sc_pps, (sc->sc_msr & SER_CTS) ? + PPS_CAPTURECLEAR : PPS_CAPTUREASSERT); + } + break; + case 2: + if ((sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) && + (msr_delta & SER_DCD)) { + pps_capture(&sc->sc_pps); + pps_event(&sc->sc_pps, (sc->sc_msr & SER_DCD) ? + PPS_CAPTURECLEAR : PPS_CAPTUREASSERT); + } + break; + default: + break; + } + + if (msr_delta & SER_DCD) { - onoff = (sc->sc_msr & SER_DCD) ? 1 : 0; + int onoff = (sc->sc_msr & SER_DCD) ? 1 : 0; DPRINTF("DCD changed to %d\n", onoff); Modified: stable/10/sys/dev/usb/serial/usb_serial.h ============================================================================== --- stable/10/sys/dev/usb/serial/usb_serial.h Sat May 23 23:35:19 2015 (r283340) +++ stable/10/sys/dev/usb/serial/usb_serial.h Sun May 24 00:53:43 2015 (r283341) @@ -64,6 +64,7 @@ #include #include #include +#include /* Module interface related macros */ #define UCOM_MODVER 1 @@ -155,6 +156,8 @@ struct ucom_softc { struct ucom_cfg_task sc_line_state_task[2]; struct ucom_cfg_task sc_status_task[2]; struct ucom_param_task sc_param_task[2]; + /* pulse capturing support, PPS */ + struct pps_state sc_pps; /* Used to set "UCOM_FLAG_GP_DATA" flag: */ struct usb_proc_msg *sc_last_start_xfer; const struct ucom_callback *sc_callback; Modified: stable/10/sys/kern/kern_tc.c ============================================================================== --- stable/10/sys/kern/kern_tc.c Sat May 23 23:35:19 2015 (r283340) +++ stable/10/sys/kern/kern_tc.c Sun May 24 00:53:43 2015 (r283341) @@ -23,10 +23,8 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifdef FFCLOCK #include #include -#endif #include #include #include @@ -1462,6 +1460,17 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, * RFC 2783 PPS-API implementation. */ +/* + * Return true if the driver is aware of the abi version extensions in the + * pps_state structure, and it supports at least the given abi version number. + */ +static inline int +abi_aware(struct pps_state *pps, int vers) +{ + + return ((pps->kcmode & KCMODE_ABIFLAG) && pps->driver_abi >= vers); +} + static int pps_fetch(struct pps_fetch_args *fapi, struct pps_state *pps) { @@ -1491,7 +1500,17 @@ pps_fetch(struct pps_fetch_args *fapi, s cseq = pps->ppsinfo.clear_sequence; while (aseq == pps->ppsinfo.assert_sequence && cseq == pps->ppsinfo.clear_sequence) { - err = tsleep(pps, PCATCH, "ppsfch", timo); + if (abi_aware(pps, 1) && pps->driver_mtx != NULL) { + if (pps->flags & PPSFLAG_MTX_SPIN) { + err = msleep_spin(pps, pps->driver_mtx, + "ppsfch", timo); + } else { + err = msleep(pps, pps->driver_mtx, PCATCH, + "ppsfch", timo); + } + } else { + err = tsleep(pps, PCATCH, "ppsfch", timo); + } if (err == EWOULDBLOCK && fapi->timeout.tv_sec == -1) { continue; } else if (err != 0) { @@ -1581,7 +1600,8 @@ pps_ioctl(u_long cmd, caddr_t data, stru return (EINVAL); if (kapi->edge & ~pps->ppscap) return (EINVAL); - pps->kcmode = kapi->edge; + pps->kcmode = (kapi->edge & KCMODE_EDGEMASK) | + (pps->kcmode & KCMODE_ABIFLAG); return (0); #else return (EOPNOTSUPP); @@ -1602,6 +1622,18 @@ pps_init(struct pps_state *pps) #ifdef FFCLOCK pps->ppscap |= PPS_TSCLK_MASK; #endif + pps->kcmode &= ~KCMODE_ABIFLAG; +} + +void +pps_init_abi(struct pps_state *pps) +{ + + pps_init(pps); + if (pps->driver_abi > 0) { + pps->kcmode |= KCMODE_ABIFLAG; + pps->kernel_abi = PPS_ABI_VERSION; + } } void Modified: stable/10/sys/sys/param.h ============================================================================== --- stable/10/sys/sys/param.h Sat May 23 23:35:19 2015 (r283340) +++ stable/10/sys/sys/param.h Sun May 24 00:53:43 2015 (r283341) @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1001515 /* Master, propagated to newvers */ +#define __FreeBSD_version 1001516 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, Modified: stable/10/sys/sys/timepps.h ============================================================================== --- stable/10/sys/sys/timepps.h Sat May 23 23:35:19 2015 (r283340) +++ stable/10/sys/sys/timepps.h Sun May 24 00:53:43 2015 (r283341) @@ -133,6 +133,15 @@ struct pps_kcbind_args { #ifdef _KERNEL +struct mtx; + +#define KCMODE_EDGEMASK 0x03 +#define KCMODE_ABIFLAG 0x80000000 /* Internal use: abi-aware driver. */ + +#define PPS_ABI_VERSION 1 + +#define PPSFLAG_MTX_SPIN 0x01 /* Driver mtx is MTX_SPIN type. */ + struct pps_state { /* Capture information. */ struct timehands *capth; @@ -148,11 +157,19 @@ struct pps_state { int ppscap; struct timecounter *ppstc; unsigned ppscount[3]; + /* + * The following fields are valid if the driver calls pps_init_abi(). + */ + uint16_t driver_abi; /* Driver sets before pps_init_abi(). */ + uint16_t kernel_abi; /* Kernel sets during pps_init_abi(). */ + struct mtx *driver_mtx; /* Optional, valid if non-NULL. */ + uint32_t flags; }; void pps_capture(struct pps_state *pps); void pps_event(struct pps_state *pps, int event); void pps_init(struct pps_state *pps); +void pps_init_abi(struct pps_state *pps); int pps_ioctl(unsigned long cmd, caddr_t data, struct pps_state *pps); void hardpps(struct timespec *tsp, long nsec);