svn commit: r283341 - in stable/10/sys: dev/usb/serial kern sys
Ian Lepore
ian at FreeBSD.org
Sun May 24 00:53:45 UTC 2015
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 <sys/serial.h>
#include <sys/fcntl.h>
#include <sys/sysctl.h>
+#include <sys/timepps.h>
/* 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 <sys/param.h>
#include <sys/kernel.h>
#include <sys/limits.h>
-#ifdef FFCLOCK
#include <sys/lock.h>
#include <sys/mutex.h>
-#endif
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/systm.h>
@@ -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);
More information about the svn-src-stable-10
mailing list