Fix NTP PPSAPI support (enabled with "options PPS_SYNC"):

From PR kern/13702 from Charles Carvalho.  Tested on alpha and
i386 with a Laipac TF10 PPS-capable GPS.  The com.c change was
copied wholesale from Charles' z8530tty.c patch.
This commit is contained in:
simonb 2004-01-23 05:01:19 +00:00
parent 359d88a947
commit 2763a4b916
5 changed files with 87 additions and 40 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: com.c,v 1.223 2003/11/12 06:27:59 simonb Exp $ */
/* $NetBSD: com.c,v 1.224 2004/01/23 05:01:19 simonb Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -73,13 +73,14 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.223 2003/11/12 06:27:59 simonb Exp $");
__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.224 2004/01/23 05:01:19 simonb Exp $");
#include "opt_com.h"
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_lockdebug.h"
#include "opt_multiprocessor.h"
#include "opt_ntp.h"
#include "rnd.h"
#if NRND > 0 && defined(RND_COM)
@ -215,9 +216,6 @@ static int ppscap =
PPS_TSFMT_TSPEC |
PPS_CAPTUREASSERT |
PPS_CAPTURECLEAR |
#ifdef PPS_SYNC
PPS_HARDPPSONASSERT | PPS_HARDPPSONCLEAR |
#endif /* PPS_SYNC */
PPS_OFFSETASSERT | PPS_OFFSETCLEAR;
#ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
@ -1120,16 +1118,6 @@ comioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Compute msr masks from user-specified timestamp state.
*/
mode = sc->ppsparam.mode;
#ifdef PPS_SYNC
if (mode & PPS_HARDPPSONASSERT) {
mode |= PPS_CAPTUREASSERT;
/* XXX revoke any previous HARDPPS source */
}
if (mode & PPS_HARDPPSONCLEAR) {
mode |= PPS_CAPTURECLEAR;
/* XXX revoke any previous HARDPPS source */
}
#endif /* PPS_SYNC */
switch (mode & PPS_CAPTUREBOTH) {
case 0:
sc->sc_ppsmask = 0;
@ -1171,6 +1159,32 @@ comioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
break;
}
#ifdef PPS_SYNC
case PPS_IOC_KCBIND: {
int edge = (*(int *)data) & PPS_CAPTUREBOTH;
if (edge == 0) {
/*
* remove binding for this source; ignore
* the request if this is not the current
* hardpps source
*/
if (pps_kc_hardpps_source == sc) {
pps_kc_hardpps_source = NULL;
pps_kc_hardpps_mode = 0;
}
} else {
/*
* bind hardpps to this source, replacing any
* previously specified source or edges
*/
pps_kc_hardpps_source = sc;
pps_kc_hardpps_mode = edge;
}
break;
}
#endif /* PPS_SYNC */
case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */
/*
* Some GPS clocks models use the falling rather than
@ -2166,8 +2180,10 @@ again: do {
}
#ifdef PPS_SYNC
if (sc->ppsparam.mode & PPS_HARDPPSONASSERT)
if (pps_kc_hardpps_source == sc &&
pps_kc_hardpps_mode & PPS_CAPTUREASSERT) {
hardpps(&tv, tv.tv_usec);
}
#endif
sc->ppsinfo.assert_sequence++;
sc->ppsinfo.current_mode = sc->ppsparam.mode;
@ -2184,8 +2200,10 @@ again: do {
}
#ifdef PPS_SYNC
if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR)
if (pps_kc_hardpps_source == sc &&
pps_kc_hardpps_mode & PPS_CAPTURECLEAR) {
hardpps(&tv, tv.tv_usec);
}
#endif
sc->ppsinfo.clear_sequence++;
sc->ppsinfo.current_mode = sc->ppsparam.mode;

View File

@ -1,4 +1,4 @@
/* $NetBSD: z8530tty.c,v 1.93 2003/12/04 13:57:30 keihan Exp $ */
/* $NetBSD: z8530tty.c,v 1.94 2004/01/23 05:01:19 simonb Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999
@ -137,9 +137,10 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: z8530tty.c,v 1.93 2003/12/04 13:57:30 keihan Exp $");
__KERNEL_RCSID(0, "$NetBSD: z8530tty.c,v 1.94 2004/01/23 05:01:19 simonb Exp $");
#include "opt_kgdb.h"
#include "opt_ntp.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -186,9 +187,6 @@ static int zsppscap =
PPS_TSFMT_TSPEC |
PPS_CAPTUREASSERT |
PPS_CAPTURECLEAR |
#ifdef PPS_SYNC
PPS_HARDPPSONASSERT | PPS_HARDPPSONCLEAR |
#endif /* PPS_SYNC */
PPS_OFFSETASSERT | PPS_OFFSETCLEAR;
struct zstty_softc {
@ -863,16 +861,6 @@ zsioctl(dev, cmd, data, flag, p)
* compute masks from user-specified timestamp state.
*/
mode = zst->ppsparam.mode;
#ifdef PPS_SYNC
if (mode & PPS_HARDPPSONASSERT) {
mode |= PPS_CAPTUREASSERT;
/* XXX revoke any previous HARDPPS source */
}
if (mode & PPS_HARDPPSONCLEAR) {
mode |= PPS_CAPTURECLEAR;
/* XXX revoke any previous HARDPPS source */
}
#endif /* PPS_SYNC */
switch (mode & PPS_CAPTUREBOTH) {
case 0:
zst->zst_ppsmask = 0;
@ -932,6 +920,32 @@ zsioctl(dev, cmd, data, flag, p)
break;
}
#ifdef PPS_SYNC
case PPS_IOC_KCBIND: {
int edge = (*(int *)data) & PPS_CAPTUREBOTH;
if (edge == 0) {
/*
* remove binding for this source; ignore
* the request if this is not the current
* hardpps source
*/
if (pps_kc_hardpps_source == zst) {
pps_kc_hardpps_source = NULL;
pps_kc_hardpps_mode = 0;
}
} else {
/*
* bind hardpps to this source, replacing any
* previously specified source or edges
*/
pps_kc_hardpps_source = zst;
pps_kc_hardpps_mode = edge;
}
break;
}
#endif /* PPS_SYNC */
case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */
if (cs->cs_rr0_pps == 0) {
error = EINVAL;
@ -1635,8 +1649,10 @@ zstty_stint(cs, force)
}
#ifdef PPS_SYNC
if (zst->ppsparam.mode & PPS_HARDPPSONASSERT)
if (pps_kc_hardpps_source == zst &&
pps_kc_hardpps_mode & PPS_CAPTUREASSERT) {
hardpps(&tv, tv.tv_usec);
}
#endif
zst->ppsinfo.assert_sequence++;
zst->ppsinfo.current_mode = zst->ppsparam.mode;
@ -1653,8 +1669,10 @@ zstty_stint(cs, force)
}
#ifdef PPS_SYNC
if (zst->ppsparam.mode & PPS_HARDPPSONCLEAR)
if (pps_kc_hardpps_source == zst &&
pps_kc_hardpps_mode & PPS_CAPTURECLEAR) {
hardpps(&tv, tv.tv_usec);
}
#endif
zst->ppsinfo.clear_sequence++;
zst->ppsinfo.current_mode = zst->ppsparam.mode;

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_clock.c,v 1.88 2003/12/04 19:38:23 atatat Exp $ */
/* $NetBSD: kern_clock.c,v 1.89 2004/01/23 05:01:19 simonb Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_clock.c,v 1.88 2003/12/04 19:38:23 atatat Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_clock.c,v 1.89 2004/01/23 05:01:19 simonb Exp $");
#include "opt_ntp.h"
#include "opt_multiprocessor.h"
@ -230,6 +230,13 @@ long time_reftime = 0; /* time at last adjustment (s) */
*
* pps_intcnt counts the calibration intervals for use in the interval-
* adaptation algorithm. It's just too complicated for words.
*
* pps_kc_hardpps_source contains an arbitrary value that uniquely
* identifies the currently bound source of the PPS signal, or NULL
* if no source is bound.
*
* pps_kc_hardpps_mode indicates which transitions, if any, of the PPS
* signal should be reported.
*/
struct timeval pps_time; /* kernel time at last interval */
long pps_tf[] = {0, 0, 0}; /* pps time offset median filter (us) */
@ -244,6 +251,8 @@ int pps_glitch = 0; /* pps signal glitch counter */
int pps_count = 0; /* calibration interval counter (s) */
int pps_shift = PPS_SHIFT; /* interval duration (s) (shift) */
int pps_intcnt = 0; /* intervals at current duration */
void *pps_kc_hardpps_source = NULL; /* current PPS supplier's identifier */
int pps_kc_hardpps_mode = 0; /* interesting edges of PPS signal */
/*
* PPS signal quality monitors

View File

@ -1,4 +1,4 @@
/* $NetBSD: systm.h,v 1.169 2003/12/30 18:29:43 thorpej Exp $ */
/* $NetBSD: systm.h,v 1.170 2004/01/23 05:01:19 simonb Exp $ */
/*-
* Copyright (c) 1982, 1988, 1991, 1993
@ -265,6 +265,8 @@ void statclock __P((struct clockframe *));
void hardupdate __P((long offset));
#ifdef PPS_SYNC
void hardpps __P((struct timeval *, long));
extern void *pps_kc_hardpps_source;
extern int pps_kc_hardpps_mode;
#endif
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: timepps.h,v 1.5 2003/07/08 06:18:00 itojun Exp $ */
/* $NetBSD: timepps.h,v 1.6 2004/01/23 05:01:19 simonb Exp $ */
/*
* Copyright (c) 1998 Jonathan Stone
@ -127,7 +127,7 @@ typedef struct {
#define PPS_IOC_GETPARAMS _IOR('1', 4, pps_params_t)
#define PPS_IOC_GETCAP _IOR('1', 5, int)
#define PPS_IOC_FETCH _IOWR('1', 6, pps_info_t)
#define PPS_IOC_KCBIND _IOWR('1', 7, int)
#define PPS_IOC_KCBIND _IOW('1', 7, int)
#ifndef _KERNEL
@ -207,7 +207,7 @@ time_pps_kcbind(handle, kernel_consumer, edge, tsformat)
const int edge;
const int tsformat;
{
return (ioctl(handle, PPS_IOC_KCBIND, edge));
return (ioctl(handle, PPS_IOC_KCBIND, &edge));
}
#endif /* !_KERNEL*/