Introduce std_pps_ioctl() to automagically DTRT.
Add scaling capability to timex.offset, ntpd-4.0.73 will support this.
This commit is contained in:
parent
9d3f194df3
commit
938ee3ce4d
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: pps.c,v 1.6 1998/06/08 02:43:12 bde Exp $
|
||||
* $Id: pps.c,v 1.7 1998/06/12 23:15:53 phk Exp $
|
||||
*
|
||||
* This driver implements a draft-mogul-pps-api-02.txt PPS source.
|
||||
*
|
||||
@ -180,40 +180,10 @@ static int
|
||||
ppsioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
|
||||
{
|
||||
struct pps_data *sc = softc[minor(dev)];
|
||||
pps_params_t *pp;
|
||||
pps_info_t *pi;
|
||||
|
||||
switch (cmd) {
|
||||
case PPS_IOC_CREATE:
|
||||
return (0);
|
||||
case PPS_IOC_DESTROY:
|
||||
return (0);
|
||||
case PPS_IOC_SETPARAMS:
|
||||
pp = (pps_params_t *)data;
|
||||
if (pp->mode & ~ppscap)
|
||||
return (EINVAL);
|
||||
sc->ppsparam = *pp;
|
||||
return (0);
|
||||
case PPS_IOC_GETPARAMS:
|
||||
pp = (pps_params_t *)data;
|
||||
*pp = sc->ppsparam;
|
||||
return (0);
|
||||
case PPS_IOC_GETCAP:
|
||||
*(int*)data = ppscap;
|
||||
return (0);
|
||||
case PPS_IOC_FETCH:
|
||||
pi = (pps_info_t *)data;
|
||||
*pi = sc->ppsinfo;
|
||||
pi->current_mode = sc->ppsparam.mode;
|
||||
return (0);
|
||||
case PPS_IOC_WAIT:
|
||||
return (EOPNOTSUPP);
|
||||
default:
|
||||
return (ENODEV);
|
||||
}
|
||||
return (std_pps_ioctl(cmd, data, &sc->ppsparam, &sc->ppsinfo, ppscap));
|
||||
}
|
||||
|
||||
|
||||
static pps_devsw_installed = 0;
|
||||
|
||||
static void
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/timex.h>
|
||||
#include <sys/timepps.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
/*
|
||||
@ -201,7 +202,7 @@ static long pps_errcnt = 0; /* calibration errors */
|
||||
static long pps_stbcnt = 0; /* stability limit exceeded */
|
||||
#endif /* PPS_SYNC */
|
||||
|
||||
static void hardupdate __P((long offset));
|
||||
static void hardupdate __P((int64_t offset, int prescaled));
|
||||
|
||||
/*
|
||||
* hardupdate() - local clock update
|
||||
@ -226,28 +227,33 @@ static void hardupdate __P((long offset));
|
||||
* Note: splclock() is in effect.
|
||||
*/
|
||||
static void
|
||||
hardupdate(offset)
|
||||
long offset;
|
||||
hardupdate(offset, prescaled)
|
||||
int64_t offset;
|
||||
int prescaled;
|
||||
{
|
||||
long ltemp, mtemp;
|
||||
long mtemp;
|
||||
int64_t ltemp;
|
||||
|
||||
if (!(time_status & STA_PLL) && !(time_status & STA_PPSTIME))
|
||||
return;
|
||||
ltemp = offset;
|
||||
if (prescaled)
|
||||
ltemp = offset;
|
||||
else
|
||||
ltemp = offset << SHIFT_UPDATE;
|
||||
#ifdef PPS_SYNC
|
||||
if (time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL)
|
||||
ltemp = pps_offset;
|
||||
ltemp = pps_offset << SHIFT_UPDATE;
|
||||
#endif /* PPS_SYNC */
|
||||
|
||||
/*
|
||||
* Scale the phase adjustment and clamp to the operating range.
|
||||
*/
|
||||
if (ltemp > MAXPHASE)
|
||||
if (ltemp > (MAXPHASE << SHIFT_UPDATE))
|
||||
time_offset = MAXPHASE << SHIFT_UPDATE;
|
||||
else if (ltemp < -MAXPHASE)
|
||||
else if (ltemp < -(MAXPHASE << SHIFT_UPDATE))
|
||||
time_offset = -(MAXPHASE << SHIFT_UPDATE);
|
||||
else
|
||||
time_offset = ltemp << SHIFT_UPDATE;
|
||||
time_offset = ltemp;
|
||||
|
||||
/*
|
||||
* Select whether the frequency is to be controlled and in which
|
||||
@ -269,15 +275,15 @@ hardupdate(offset)
|
||||
}
|
||||
} else {
|
||||
if (mtemp < MAXSEC) {
|
||||
ltemp *= mtemp;
|
||||
ltemp = time_offset * mtemp;
|
||||
if (ltemp < 0)
|
||||
time_freq -= -ltemp >> (time_constant +
|
||||
time_freq -= -ltemp >> ((int64_t)time_constant +
|
||||
time_constant + SHIFT_KF -
|
||||
SHIFT_USEC);
|
||||
SHIFT_USEC + SHIFT_UPDATE);
|
||||
else
|
||||
time_freq += ltemp >> (time_constant +
|
||||
time_freq += ltemp >> ((int64_t)time_constant +
|
||||
time_constant + SHIFT_KF -
|
||||
SHIFT_USEC);
|
||||
SHIFT_USEC + SHIFT_UPDATE);
|
||||
}
|
||||
}
|
||||
if (time_freq > time_tolerance)
|
||||
@ -525,12 +531,15 @@ ntp_adjtime(struct proc *p, struct ntp_adjtime_args *uap)
|
||||
if (modes & MOD_TIMECONST)
|
||||
time_constant = ntv.constant;
|
||||
if (modes & MOD_OFFSET)
|
||||
hardupdate(ntv.offset);
|
||||
hardupdate(ntv.offset, modes & MOD_DOSCALE);
|
||||
|
||||
ntv.modes |= MOD_CANSCALE;
|
||||
/*
|
||||
* Retrieve all clock variables
|
||||
*/
|
||||
if (time_offset < 0)
|
||||
if (modes & MOD_DOSCALE)
|
||||
ntv.offset = time_offset;
|
||||
else if (time_offset < 0)
|
||||
ntv.offset = -(-time_offset >> SHIFT_UPDATE);
|
||||
else
|
||||
ntv.offset = time_offset >> SHIFT_UPDATE;
|
||||
@ -809,3 +818,39 @@ hardpps(tvp, p_usec)
|
||||
}
|
||||
|
||||
#endif /* PPS_SYNC */
|
||||
|
||||
int
|
||||
std_pps_ioctl(u_long cmd, caddr_t data, pps_params_t *pp, pps_info_t *pi, int ppscap)
|
||||
{
|
||||
pps_params_t *app;
|
||||
pps_info_t *api;
|
||||
|
||||
switch (cmd) {
|
||||
case PPS_IOC_CREATE:
|
||||
return (0);
|
||||
case PPS_IOC_DESTROY:
|
||||
return (0);
|
||||
case PPS_IOC_SETPARAMS:
|
||||
app = (pps_params_t *)data;
|
||||
if (app->mode & ~ppscap)
|
||||
return (EINVAL);
|
||||
*pp = *app;
|
||||
return (0);
|
||||
case PPS_IOC_GETPARAMS:
|
||||
app = (pps_params_t *)data;
|
||||
*app = *pp;
|
||||
return (0);
|
||||
case PPS_IOC_GETCAP:
|
||||
*(int*)data = ppscap;
|
||||
return (0);
|
||||
case PPS_IOC_FETCH:
|
||||
api = (pps_info_t *)data;
|
||||
*api = *pi;
|
||||
pi->current_mode = pp->mode;
|
||||
return (0);
|
||||
case PPS_IOC_WAIT:
|
||||
return (EOPNOTSUPP);
|
||||
default:
|
||||
return (ENODEV);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: timepps.h,v 1.1 1998/06/07 19:44:16 phk Exp $
|
||||
* $Id: timepps.h,v 1.2 1998/06/12 23:15:40 phk Exp $
|
||||
*
|
||||
* The is a FreeBSD protype version of the "draft-mogul-pps-api-02.txt"
|
||||
* specification for Pulse Per Second timing interfaces.
|
||||
@ -91,4 +91,9 @@ struct pps_wait_args {
|
||||
#define PPS_IOC_FETCH _IOWR('1', 6, pps_info_t)
|
||||
#define PPS_IOC_WAIT _IOWR('1', 6, struct pps_wait_args)
|
||||
|
||||
#ifdef KERNEL
|
||||
int std_pps_ioctl __P((u_long cmd, caddr_t data, pps_params_t *pp,
|
||||
pps_info_t *pi, int ppscap));
|
||||
|
||||
#endif /* KERNEL */
|
||||
#endif /* _SYS_TIMEPPS_H_ */
|
||||
|
@ -202,8 +202,8 @@
|
||||
#define MOD_ESTERROR 0x0008 /* set estimated time error */
|
||||
#define MOD_STATUS 0x0010 /* set clock status bits */
|
||||
#define MOD_TIMECONST 0x0020 /* set pll time constant */
|
||||
#define MOD_CLKB 0x4000 /* set clock B */
|
||||
#define MOD_CLKA 0x8000 /* set clock A */
|
||||
#define MOD_CANSCALE 0x0040 /* kernel can scale offset field */
|
||||
#define MOD_DOSCALE 0x0080 /* userland wants to scale offset field */
|
||||
|
||||
/*
|
||||
* Status codes (timex.status)
|
||||
|
Loading…
x
Reference in New Issue
Block a user