summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_tc.c
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2015-05-24 00:53:43 +0000
committerian <ian@FreeBSD.org>2015-05-24 00:53:43 +0000
commitb92e1caf1c5b2306f5e063f527bd371698b7d10f (patch)
tree8f7fa47666de8fdcc1a7c474d91250001d7249e1 /sys/kern/kern_tc.c
parent884316392ad48186d3e882c810123f020c4df56b (diff)
downloadFreeBSD-src-b92e1caf1c5b2306f5e063f527bd371698b7d10f.zip
FreeBSD-src-b92e1caf1c5b2306f5e063f527bd371698b7d10f.tar.gz
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.
Diffstat (limited to 'sys/kern/kern_tc.c')
-rw-r--r--sys/kern/kern_tc.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index d671da5..acb0fbf 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -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, choice, CTLTYPE_STRING | CTLFLAG_RD,
* 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, struct pps_state *pps)
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, struct pps_state *pps)
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
OpenPOWER on IntegriCloud