summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1998-06-13 09:30:26 +0000
committerphk <phk@FreeBSD.org>1998-06-13 09:30:26 +0000
commit885f9e9d51aad3937cd0b5958dc4547208187eb3 (patch)
tree37d60610268d012ff6fd0d03e72fcee6d7cbde9d
parent98ec89f1825fc700e6d9bce147a026b4036af855 (diff)
downloadFreeBSD-src-885f9e9d51aad3937cd0b5958dc4547208187eb3.zip
FreeBSD-src-885f9e9d51aad3937cd0b5958dc4547208187eb3.tar.gz
Introduce std_pps_ioctl() to automagically DTRT.
Add scaling capability to timex.offset, ntpd-4.0.73 will support this.
-rw-r--r--sys/dev/ppbus/pps.c34
-rw-r--r--sys/kern/kern_ntptime.c77
-rw-r--r--sys/sys/timepps.h7
-rw-r--r--sys/sys/timex.h4
4 files changed, 71 insertions, 51 deletions
diff --git a/sys/dev/ppbus/pps.c b/sys/dev/ppbus/pps.c
index 74bcf0c..4a17eb161 100644
--- a/sys/dev/ppbus/pps.c
+++ b/sys/dev/ppbus/pps.c
@@ -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
diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c
index 57d386e..2f4114d 100644
--- a/sys/kern/kern_ntptime.c
+++ b/sys/kern/kern_ntptime.c
@@ -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);
+ }
+}
diff --git a/sys/sys/timepps.h b/sys/sys/timepps.h
index 78d0901..8d98804 100644
--- a/sys/sys/timepps.h
+++ b/sys/sys/timepps.h
@@ -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_ */
diff --git a/sys/sys/timex.h b/sys/sys/timex.h
index 5e0df4b..47fd808 100644
--- a/sys/sys/timex.h
+++ b/sys/sys/timex.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)
OpenPOWER on IntegriCloud