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:
Poul-Henning Kamp 1998-06-13 09:30:26 +00:00
parent 9d3f194df3
commit 938ee3ce4d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36941
4 changed files with 71 additions and 51 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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_ */

View File

@ -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)