Make even more of the PPSAPI implementations generic.
FLL support in hardpps() Various magic shuffles and improved comments Style fixes from Bruce.
This commit is contained in:
parent
d492694916
commit
32c203577a
@ -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.12 1998/12/07 21:58:16 archie Exp $
|
||||
* $Id: pps.c,v 1.13 1999/01/30 15:35:39 nsouch Exp $
|
||||
*
|
||||
* This driver implements a draft-mogul-pps-api-02.txt PPS source.
|
||||
*
|
||||
@ -16,7 +16,6 @@
|
||||
*/
|
||||
|
||||
#include "opt_devfs.h"
|
||||
#include "opt_ntp.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
@ -36,20 +35,11 @@
|
||||
static struct pps_data {
|
||||
int pps_unit;
|
||||
struct ppb_device pps_dev;
|
||||
pps_params_t ppsparam;
|
||||
pps_info_t ppsinfo;
|
||||
struct pps_state pps;
|
||||
} *softc[NPPS];
|
||||
|
||||
static int ppscap =
|
||||
PPS_CAPTUREASSERT |
|
||||
#ifdef PPS_SYNC
|
||||
PPS_HARDPPSONASSERT |
|
||||
#endif /* PPS_SYNC */
|
||||
PPS_OFFSETASSERT |
|
||||
PPS_ECHOASSERT |
|
||||
PPS_TSFMT_TSPEC;
|
||||
|
||||
static int npps;
|
||||
static pps_devsw_installed = 0;
|
||||
|
||||
/*
|
||||
* Make ourselves visible as a ppbus driver
|
||||
@ -77,6 +67,7 @@ static struct cdevsw pps_cdevsw =
|
||||
seltrue, nommap, nostrat, PPS_NAME,
|
||||
NULL, -1 };
|
||||
|
||||
|
||||
static struct ppb_device *
|
||||
ppsprobe(struct ppb_data *ppb)
|
||||
{
|
||||
@ -99,12 +90,16 @@ ppsprobe(struct ppb_data *ppb)
|
||||
sc->pps_dev.name = ppsdriver.name;
|
||||
sc->pps_dev.intr = ppsintr;
|
||||
|
||||
sc->pps.ppscap = PPS_CAPTUREASSERT | PPS_ECHOASSERT;
|
||||
pps_init(&sc->pps);
|
||||
return (&sc->pps_dev);
|
||||
}
|
||||
|
||||
static int
|
||||
ppsattach(struct ppb_device *dev)
|
||||
{
|
||||
dev_t devt;
|
||||
|
||||
/*
|
||||
* Report ourselves
|
||||
*/
|
||||
@ -116,7 +111,11 @@ ppsattach(struct ppb_device *dev)
|
||||
dev->id_unit, DV_CHR,
|
||||
UID_ROOT, GID_WHEEL, 0600, PPS_NAME "%d", dev->id_unit);
|
||||
#endif
|
||||
|
||||
if( ! pps_devsw_installed ) {
|
||||
devt = makedev(CDEV_MAJOR, 0);
|
||||
cdevsw_add(&devt, &pps_cdevsw, NULL);
|
||||
pps_devsw_installed = 1;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -145,7 +144,7 @@ ppsclose(dev_t dev, int flags, int fmt, struct proc *p)
|
||||
{
|
||||
struct pps_data *sc = softc[minor(dev)];
|
||||
|
||||
sc->ppsparam.mode = 0;
|
||||
sc->pps.ppsparam.mode = 0; /* PHK ??? */
|
||||
|
||||
ppb_wdtr(&sc->pps_dev, 0);
|
||||
ppb_wctr(&sc->pps_dev, 0);
|
||||
@ -158,32 +157,17 @@ static void
|
||||
ppsintr(int unit)
|
||||
{
|
||||
struct pps_data *sc = softc[unit];
|
||||
struct timespec tc;
|
||||
struct timecounter *tc;
|
||||
unsigned count;
|
||||
|
||||
nanotime(&tc);
|
||||
tc = timecounter;
|
||||
count = timecounter->tc_get_timecount(tc);
|
||||
if (!(ppb_rstr(&sc->pps_dev) & nACK))
|
||||
return;
|
||||
if (sc->ppsparam.mode & PPS_ECHOASSERT)
|
||||
if (sc->pps.ppsparam.mode & PPS_ECHOASSERT)
|
||||
ppb_wctr(&sc->pps_dev, IRQENABLE | AUTOFEED);
|
||||
if (sc->ppsparam.mode & PPS_OFFSETASSERT) {
|
||||
timespecadd(&tc, &sc->ppsparam.assert_offset);
|
||||
if (tc.tv_nsec < 0) {
|
||||
tc.tv_sec--;
|
||||
tc.tv_nsec += 1000000000;
|
||||
}
|
||||
}
|
||||
sc->ppsinfo.assert_timestamp = tc;
|
||||
sc->ppsinfo.assert_sequence++;
|
||||
#ifdef PPS_SYNC
|
||||
if (sc->ppsparam.mode & PPS_HARDPPSONASSERT) {
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = tc.tv_sec;
|
||||
tv.tv_usec = tc.tv_nsec / 1000;
|
||||
hardpps(&tv, tv.tv_usec);
|
||||
}
|
||||
#endif /* PPS_SYNC */
|
||||
if (sc->ppsparam.mode & PPS_ECHOASSERT)
|
||||
pps_event(&sc->pps, tc, count, PPS_CAPTUREASSERT);
|
||||
if (sc->pps.ppsparam.mode & PPS_ECHOASSERT)
|
||||
ppb_wctr(&sc->pps_dev, IRQENABLE);
|
||||
}
|
||||
|
||||
@ -192,21 +176,6 @@ ppsioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
|
||||
{
|
||||
struct pps_data *sc = softc[minor(dev)];
|
||||
|
||||
return (std_pps_ioctl(cmd, data, &sc->ppsparam, &sc->ppsinfo, ppscap));
|
||||
return (pps_ioctl(cmd, data, &sc->pps));
|
||||
}
|
||||
|
||||
static pps_devsw_installed = 0;
|
||||
|
||||
static void
|
||||
pps_drvinit(void *unused)
|
||||
{
|
||||
dev_t dev;
|
||||
|
||||
if( ! pps_devsw_installed ) {
|
||||
dev = makedev(CDEV_MAJOR, 0);
|
||||
cdevsw_add(&dev, &pps_cdevsw, NULL);
|
||||
pps_devsw_installed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
SYSINIT(ppsdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,pps_drvinit,NULL)
|
||||
|
@ -37,9 +37,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
|
||||
* $Id: kern_clock.c,v 1.88 1999/02/19 19:34:49 luoqi Exp $
|
||||
* $Id: kern_clock.c,v 1.89 1999/03/08 12:35:58 phk Exp $
|
||||
*/
|
||||
|
||||
#include "opt_ntp.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/dkstat.h>
|
||||
@ -50,6 +52,7 @@
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/timex.h>
|
||||
#include <sys/timepps.h>
|
||||
#include <vm/vm.h>
|
||||
#include <sys/lock.h>
|
||||
#include <vm/pmap.h>
|
||||
@ -509,11 +512,14 @@ tco_delta(struct timecounter *tc)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have four functions for looking at the clock, two for microseconds
|
||||
* and two for nanoseconds. For each there is fast but less precise
|
||||
* version "get{nano|micro}time" which will return a time which is up
|
||||
* to 1/HZ previous to the call, whereas the raw version "{nano|micro}time"
|
||||
* will return a timestamp which is as precise as possible.
|
||||
* We have eight functions for looking at the clock, four for
|
||||
* microseconds and four for nanoseconds. For each there is fast
|
||||
* but less precise version "get{nano|micro}[up]time" which will
|
||||
* return a time which is up to 1/HZ previous to the call, whereas
|
||||
* the raw version "{nano|micro}[up]time" will return a timestamp
|
||||
* which is as precise as possible. The "up" variants return the
|
||||
* time relative to system boot, these are well suited for time
|
||||
* interval measurements.
|
||||
*/
|
||||
|
||||
void
|
||||
@ -582,29 +588,6 @@ nanotime(struct timespec *ts)
|
||||
ts->tv_nsec = delta;
|
||||
}
|
||||
|
||||
void
|
||||
timecounter_timespec(unsigned count, struct timespec *ts)
|
||||
{
|
||||
u_int64_t delta;
|
||||
struct timecounter *tc;
|
||||
|
||||
tc = (struct timecounter *)timecounter;
|
||||
ts->tv_sec = tc->tc_offset_sec;
|
||||
count -= tc->tc_offset_count;
|
||||
count &= tc->tc_counter_mask;
|
||||
delta = tc->tc_offset_nano;
|
||||
delta += ((u_int64_t)count * tc->tc_scale_nano_f);
|
||||
delta >>= 32;
|
||||
delta += ((u_int64_t)count * tc->tc_scale_nano_i);
|
||||
delta += boottime.tv_usec * 1000;
|
||||
ts->tv_sec += boottime.tv_sec;
|
||||
while (delta >= 1000000000) {
|
||||
delta -= 1000000000;
|
||||
ts->tv_sec++;
|
||||
}
|
||||
ts->tv_nsec = delta;
|
||||
}
|
||||
|
||||
void
|
||||
getmicrouptime(struct timeval *tvp)
|
||||
{
|
||||
@ -805,8 +788,6 @@ tco_forward(int force)
|
||||
while (tc->tc_offset_nano >= 1000000000ULL << 32) {
|
||||
tc->tc_offset_nano -= 1000000000ULL << 32;
|
||||
tc->tc_offset_sec++;
|
||||
tc->tc_frequency = tc->tc_tweak->tc_frequency;
|
||||
tc->tc_adjustment = tc->tc_tweak->tc_adjustment;
|
||||
ntp_update_second(tc); /* XXX only needed if xntpd runs */
|
||||
tco_setscales(tc);
|
||||
force++;
|
||||
@ -832,24 +813,6 @@ tco_forward(int force)
|
||||
timecounter = tc;
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_kern_timecounter_frequency SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
|
||||
return (sysctl_handle_opaque(oidp,
|
||||
&timecounter->tc_tweak->tc_frequency,
|
||||
sizeof(timecounter->tc_tweak->tc_frequency), req));
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_kern_timecounter_adjustment SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
|
||||
return (sysctl_handle_opaque(oidp,
|
||||
&timecounter->tc_tweak->tc_adjustment,
|
||||
sizeof(timecounter->tc_tweak->tc_adjustment), req));
|
||||
}
|
||||
|
||||
SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, "");
|
||||
|
||||
SYSCTL_INT(_kern_timecounter, KERN_ARGMAX, method, CTLFLAG_RW, &tco_method, 0,
|
||||
@ -859,8 +822,140 @@ SYSCTL_INT(_kern_timecounter, KERN_ARGMAX, method, CTLFLAG_RW, &tco_method, 0,
|
||||
|
||||
);
|
||||
|
||||
SYSCTL_PROC(_kern_timecounter, OID_AUTO, frequency, CTLTYPE_INT | CTLFLAG_RW,
|
||||
0, sizeof(u_int), sysctl_kern_timecounter_frequency, "I", "");
|
||||
|
||||
SYSCTL_PROC(_kern_timecounter, OID_AUTO, adjustment, CTLTYPE_INT | CTLFLAG_RW,
|
||||
0, sizeof(int), sysctl_kern_timecounter_adjustment, "I", "");
|
||||
int
|
||||
pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)
|
||||
{
|
||||
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 & ~pps->ppscap)
|
||||
return (EINVAL);
|
||||
pps->ppsparam = *app;
|
||||
return (0);
|
||||
case PPS_IOC_GETPARAMS:
|
||||
app = (pps_params_t *)data;
|
||||
*app = pps->ppsparam;
|
||||
return (0);
|
||||
case PPS_IOC_GETCAP:
|
||||
*(int*)data = pps->ppscap;
|
||||
return (0);
|
||||
case PPS_IOC_FETCH:
|
||||
api = (pps_info_t *)data;
|
||||
pps->ppsinfo.current_mode = pps->ppsparam.mode;
|
||||
*api = pps->ppsinfo;
|
||||
return (0);
|
||||
case PPS_IOC_WAIT:
|
||||
return (EOPNOTSUPP);
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pps_init(struct pps_state *pps)
|
||||
{
|
||||
pps->ppscap |= PPS_TSFMT_TSPEC;
|
||||
if (pps->ppscap & PPS_CAPTUREASSERT)
|
||||
pps->ppscap |= PPS_OFFSETASSERT;
|
||||
if (pps->ppscap & PPS_CAPTURECLEAR)
|
||||
pps->ppscap |= PPS_OFFSETCLEAR;
|
||||
#ifdef PPS_SYNC
|
||||
if (pps->ppscap & PPS_CAPTUREASSERT)
|
||||
pps->ppscap |= PPS_HARDPPSONASSERT;
|
||||
if (pps->ppscap & PPS_CAPTURECLEAR)
|
||||
pps->ppscap |= PPS_HARDPPSONCLEAR;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
pps_event(struct pps_state *pps, struct timecounter *tc, unsigned count, int event)
|
||||
{
|
||||
struct timespec ts, *tsp, *osp;
|
||||
u_int64_t delta;
|
||||
unsigned tcount, *pcount;
|
||||
int foff, fhard;
|
||||
pps_seq_t *pseq;
|
||||
|
||||
/* Things would be easier with arrays... */
|
||||
if (event == PPS_CAPTUREASSERT) {
|
||||
tsp = &pps->ppsinfo.assert_timestamp;
|
||||
osp = &pps->ppsparam.assert_offset;
|
||||
foff = pps->ppsparam.mode & PPS_OFFSETASSERT;
|
||||
fhard = pps->ppsparam.mode & PPS_HARDPPSONASSERT;
|
||||
pcount = &pps->ppscount[0];
|
||||
pseq = &pps->ppsinfo.assert_sequence;
|
||||
} else {
|
||||
tsp = &pps->ppsinfo.clear_timestamp;
|
||||
osp = &pps->ppsparam.clear_offset;
|
||||
foff = pps->ppsparam.mode & PPS_OFFSETCLEAR;
|
||||
fhard = pps->ppsparam.mode & PPS_HARDPPSONCLEAR;
|
||||
pcount = &pps->ppscount[1];
|
||||
pseq = &pps->ppsinfo.clear_sequence;
|
||||
}
|
||||
|
||||
/* The timecounter changed: bail */
|
||||
if (!pps->ppstc ||
|
||||
pps->ppstc->tc_name != tc->tc_name ||
|
||||
tc->tc_name != timecounter->tc_name) {
|
||||
pps->ppstc = tc;
|
||||
*pcount = count;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now, make sure we have the right instance */
|
||||
tc = timecounter;
|
||||
|
||||
/* Nothing really happened */
|
||||
if (*pcount == count)
|
||||
return;
|
||||
|
||||
*pcount = count;
|
||||
|
||||
/* Convert the count to timespec */
|
||||
ts.tv_sec = tc->tc_offset_sec;
|
||||
tcount = count - tc->tc_offset_count;
|
||||
tcount &= tc->tc_counter_mask;
|
||||
delta = tc->tc_offset_nano;
|
||||
delta += ((u_int64_t)tcount * tc->tc_scale_nano_f);
|
||||
delta >>= 32;
|
||||
delta += ((u_int64_t)tcount * tc->tc_scale_nano_i);
|
||||
delta += boottime.tv_usec * 1000;
|
||||
ts.tv_sec += boottime.tv_sec;
|
||||
while (delta >= 1000000000) {
|
||||
delta -= 1000000000;
|
||||
ts.tv_sec++;
|
||||
}
|
||||
ts.tv_nsec = delta;
|
||||
|
||||
(*pseq)++;
|
||||
*tsp = ts;
|
||||
|
||||
if (foff) {
|
||||
timespecadd(tsp, osp);
|
||||
if (tsp->tv_nsec < 0) {
|
||||
tsp->tv_nsec += 1000000000;
|
||||
tsp->tv_sec -= 1;
|
||||
}
|
||||
}
|
||||
#ifdef PPS_SYNC
|
||||
if (fhard) {
|
||||
/* magic, at its best... */
|
||||
tcount = count - pps->ppscount[2];
|
||||
pps->ppscount[2] = count;
|
||||
tcount &= tc->tc_counter_mask;
|
||||
delta = ((u_int64_t)tcount * tc->tc_tweak->tc_scale_nano_f);
|
||||
delta >>= 32;
|
||||
delta += ((u_int64_t)tcount * tc->tc_tweak->tc_scale_nano_i);
|
||||
hardpps(tsp, delta);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
/*
|
||||
* Adapted from the original sources for FreeBSD and timecounters by:
|
||||
* Poul-Henning Kamp <phk@FreeBSD.org>
|
||||
* Poul-Henning Kamp <phk@FreeBSD.org>.
|
||||
*
|
||||
* The 32bit version of the "LP" macros seems a bit past its "sell by"
|
||||
* date so I have retained only the 64bit version and included it directly
|
||||
@ -27,11 +27,10 @@
|
||||
* Only minor changes done to interface with the timecounters over in
|
||||
* sys/kern/kern_clock.c. Some of the comments below may be (even more)
|
||||
* confusing and/or plain wrong in that context.
|
||||
*
|
||||
* The PPS_SYNC/hardpps() is currently not supported.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "opt_ntp.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysproto.h>
|
||||
@ -167,7 +166,6 @@ struct ppstime {
|
||||
static struct ppstime pps_tf[3]; /* phase median filter */
|
||||
static struct ppstime pps_filt; /* phase offset */
|
||||
static l_fp pps_freq; /* scaled frequency offset (ns/s) */
|
||||
static long pps_lastfreq; /* last scaled freq offset (ns/s) */
|
||||
static long pps_offacc; /* offset accumulator */
|
||||
static long pps_jitter; /* scaled time dispersion (ns) */
|
||||
static long pps_stabil; /* scaled frequency dispersion (ns/s) */
|
||||
@ -382,7 +380,7 @@ void
|
||||
ntp_update_second(struct timecounter *tcp)
|
||||
{
|
||||
u_int32_t *newsec;
|
||||
l_fp ftemp, time_adj; /* 32/64-bit temporary */
|
||||
l_fp ftemp, time_adj; /* 32/64-bit temporaries */
|
||||
|
||||
newsec = &tcp->tc_offset_sec;
|
||||
time_maxerror += MAXFREQ / 1000;
|
||||
@ -654,16 +652,17 @@ hardpps(tsp, nsec)
|
||||
* boundary during the last second, so correct the tick. Very
|
||||
* intricate.
|
||||
*/
|
||||
u_nsec = nsec - pps_lastcount;
|
||||
pps_lastcount = nsec;
|
||||
u_nsec = nsec;
|
||||
if (u_nsec > (NANOSECOND >> 1))
|
||||
u_nsec -= NANOSECOND;
|
||||
else if (u_nsec < -(NANOSECOND >> 1))
|
||||
u_nsec += NANOSECOND;
|
||||
#if 0
|
||||
if (u_nsec > (time_tick >> 1))
|
||||
u_nsec -= time_tick;
|
||||
else if (u_nsec < -(time_tick >> 1))
|
||||
u_nsec += time_tick;
|
||||
#endif
|
||||
pps_tf[0].count = pps_tf[1].count + u_nsec;
|
||||
if (v_nsec > MAXFREQ) {
|
||||
return;
|
||||
@ -812,39 +811,3 @@ hardpps(tsp, nsec)
|
||||
time_freq = pps_freq;
|
||||
}
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
@ -37,9 +37,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
|
||||
* $Id: kern_clock.c,v 1.88 1999/02/19 19:34:49 luoqi Exp $
|
||||
* $Id: kern_clock.c,v 1.89 1999/03/08 12:35:58 phk Exp $
|
||||
*/
|
||||
|
||||
#include "opt_ntp.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/dkstat.h>
|
||||
@ -50,6 +52,7 @@
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/timex.h>
|
||||
#include <sys/timepps.h>
|
||||
#include <vm/vm.h>
|
||||
#include <sys/lock.h>
|
||||
#include <vm/pmap.h>
|
||||
@ -509,11 +512,14 @@ tco_delta(struct timecounter *tc)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have four functions for looking at the clock, two for microseconds
|
||||
* and two for nanoseconds. For each there is fast but less precise
|
||||
* version "get{nano|micro}time" which will return a time which is up
|
||||
* to 1/HZ previous to the call, whereas the raw version "{nano|micro}time"
|
||||
* will return a timestamp which is as precise as possible.
|
||||
* We have eight functions for looking at the clock, four for
|
||||
* microseconds and four for nanoseconds. For each there is fast
|
||||
* but less precise version "get{nano|micro}[up]time" which will
|
||||
* return a time which is up to 1/HZ previous to the call, whereas
|
||||
* the raw version "{nano|micro}[up]time" will return a timestamp
|
||||
* which is as precise as possible. The "up" variants return the
|
||||
* time relative to system boot, these are well suited for time
|
||||
* interval measurements.
|
||||
*/
|
||||
|
||||
void
|
||||
@ -582,29 +588,6 @@ nanotime(struct timespec *ts)
|
||||
ts->tv_nsec = delta;
|
||||
}
|
||||
|
||||
void
|
||||
timecounter_timespec(unsigned count, struct timespec *ts)
|
||||
{
|
||||
u_int64_t delta;
|
||||
struct timecounter *tc;
|
||||
|
||||
tc = (struct timecounter *)timecounter;
|
||||
ts->tv_sec = tc->tc_offset_sec;
|
||||
count -= tc->tc_offset_count;
|
||||
count &= tc->tc_counter_mask;
|
||||
delta = tc->tc_offset_nano;
|
||||
delta += ((u_int64_t)count * tc->tc_scale_nano_f);
|
||||
delta >>= 32;
|
||||
delta += ((u_int64_t)count * tc->tc_scale_nano_i);
|
||||
delta += boottime.tv_usec * 1000;
|
||||
ts->tv_sec += boottime.tv_sec;
|
||||
while (delta >= 1000000000) {
|
||||
delta -= 1000000000;
|
||||
ts->tv_sec++;
|
||||
}
|
||||
ts->tv_nsec = delta;
|
||||
}
|
||||
|
||||
void
|
||||
getmicrouptime(struct timeval *tvp)
|
||||
{
|
||||
@ -805,8 +788,6 @@ tco_forward(int force)
|
||||
while (tc->tc_offset_nano >= 1000000000ULL << 32) {
|
||||
tc->tc_offset_nano -= 1000000000ULL << 32;
|
||||
tc->tc_offset_sec++;
|
||||
tc->tc_frequency = tc->tc_tweak->tc_frequency;
|
||||
tc->tc_adjustment = tc->tc_tweak->tc_adjustment;
|
||||
ntp_update_second(tc); /* XXX only needed if xntpd runs */
|
||||
tco_setscales(tc);
|
||||
force++;
|
||||
@ -832,24 +813,6 @@ tco_forward(int force)
|
||||
timecounter = tc;
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_kern_timecounter_frequency SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
|
||||
return (sysctl_handle_opaque(oidp,
|
||||
&timecounter->tc_tweak->tc_frequency,
|
||||
sizeof(timecounter->tc_tweak->tc_frequency), req));
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_kern_timecounter_adjustment SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
|
||||
return (sysctl_handle_opaque(oidp,
|
||||
&timecounter->tc_tweak->tc_adjustment,
|
||||
sizeof(timecounter->tc_tweak->tc_adjustment), req));
|
||||
}
|
||||
|
||||
SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, "");
|
||||
|
||||
SYSCTL_INT(_kern_timecounter, KERN_ARGMAX, method, CTLFLAG_RW, &tco_method, 0,
|
||||
@ -859,8 +822,140 @@ SYSCTL_INT(_kern_timecounter, KERN_ARGMAX, method, CTLFLAG_RW, &tco_method, 0,
|
||||
|
||||
);
|
||||
|
||||
SYSCTL_PROC(_kern_timecounter, OID_AUTO, frequency, CTLTYPE_INT | CTLFLAG_RW,
|
||||
0, sizeof(u_int), sysctl_kern_timecounter_frequency, "I", "");
|
||||
|
||||
SYSCTL_PROC(_kern_timecounter, OID_AUTO, adjustment, CTLTYPE_INT | CTLFLAG_RW,
|
||||
0, sizeof(int), sysctl_kern_timecounter_adjustment, "I", "");
|
||||
int
|
||||
pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)
|
||||
{
|
||||
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 & ~pps->ppscap)
|
||||
return (EINVAL);
|
||||
pps->ppsparam = *app;
|
||||
return (0);
|
||||
case PPS_IOC_GETPARAMS:
|
||||
app = (pps_params_t *)data;
|
||||
*app = pps->ppsparam;
|
||||
return (0);
|
||||
case PPS_IOC_GETCAP:
|
||||
*(int*)data = pps->ppscap;
|
||||
return (0);
|
||||
case PPS_IOC_FETCH:
|
||||
api = (pps_info_t *)data;
|
||||
pps->ppsinfo.current_mode = pps->ppsparam.mode;
|
||||
*api = pps->ppsinfo;
|
||||
return (0);
|
||||
case PPS_IOC_WAIT:
|
||||
return (EOPNOTSUPP);
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pps_init(struct pps_state *pps)
|
||||
{
|
||||
pps->ppscap |= PPS_TSFMT_TSPEC;
|
||||
if (pps->ppscap & PPS_CAPTUREASSERT)
|
||||
pps->ppscap |= PPS_OFFSETASSERT;
|
||||
if (pps->ppscap & PPS_CAPTURECLEAR)
|
||||
pps->ppscap |= PPS_OFFSETCLEAR;
|
||||
#ifdef PPS_SYNC
|
||||
if (pps->ppscap & PPS_CAPTUREASSERT)
|
||||
pps->ppscap |= PPS_HARDPPSONASSERT;
|
||||
if (pps->ppscap & PPS_CAPTURECLEAR)
|
||||
pps->ppscap |= PPS_HARDPPSONCLEAR;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
pps_event(struct pps_state *pps, struct timecounter *tc, unsigned count, int event)
|
||||
{
|
||||
struct timespec ts, *tsp, *osp;
|
||||
u_int64_t delta;
|
||||
unsigned tcount, *pcount;
|
||||
int foff, fhard;
|
||||
pps_seq_t *pseq;
|
||||
|
||||
/* Things would be easier with arrays... */
|
||||
if (event == PPS_CAPTUREASSERT) {
|
||||
tsp = &pps->ppsinfo.assert_timestamp;
|
||||
osp = &pps->ppsparam.assert_offset;
|
||||
foff = pps->ppsparam.mode & PPS_OFFSETASSERT;
|
||||
fhard = pps->ppsparam.mode & PPS_HARDPPSONASSERT;
|
||||
pcount = &pps->ppscount[0];
|
||||
pseq = &pps->ppsinfo.assert_sequence;
|
||||
} else {
|
||||
tsp = &pps->ppsinfo.clear_timestamp;
|
||||
osp = &pps->ppsparam.clear_offset;
|
||||
foff = pps->ppsparam.mode & PPS_OFFSETCLEAR;
|
||||
fhard = pps->ppsparam.mode & PPS_HARDPPSONCLEAR;
|
||||
pcount = &pps->ppscount[1];
|
||||
pseq = &pps->ppsinfo.clear_sequence;
|
||||
}
|
||||
|
||||
/* The timecounter changed: bail */
|
||||
if (!pps->ppstc ||
|
||||
pps->ppstc->tc_name != tc->tc_name ||
|
||||
tc->tc_name != timecounter->tc_name) {
|
||||
pps->ppstc = tc;
|
||||
*pcount = count;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now, make sure we have the right instance */
|
||||
tc = timecounter;
|
||||
|
||||
/* Nothing really happened */
|
||||
if (*pcount == count)
|
||||
return;
|
||||
|
||||
*pcount = count;
|
||||
|
||||
/* Convert the count to timespec */
|
||||
ts.tv_sec = tc->tc_offset_sec;
|
||||
tcount = count - tc->tc_offset_count;
|
||||
tcount &= tc->tc_counter_mask;
|
||||
delta = tc->tc_offset_nano;
|
||||
delta += ((u_int64_t)tcount * tc->tc_scale_nano_f);
|
||||
delta >>= 32;
|
||||
delta += ((u_int64_t)tcount * tc->tc_scale_nano_i);
|
||||
delta += boottime.tv_usec * 1000;
|
||||
ts.tv_sec += boottime.tv_sec;
|
||||
while (delta >= 1000000000) {
|
||||
delta -= 1000000000;
|
||||
ts.tv_sec++;
|
||||
}
|
||||
ts.tv_nsec = delta;
|
||||
|
||||
(*pseq)++;
|
||||
*tsp = ts;
|
||||
|
||||
if (foff) {
|
||||
timespecadd(tsp, osp);
|
||||
if (tsp->tv_nsec < 0) {
|
||||
tsp->tv_nsec += 1000000000;
|
||||
tsp->tv_sec -= 1;
|
||||
}
|
||||
}
|
||||
#ifdef PPS_SYNC
|
||||
if (fhard) {
|
||||
/* magic, at its best... */
|
||||
tcount = count - pps->ppscount[2];
|
||||
pps->ppscount[2] = count;
|
||||
tcount &= tc->tc_counter_mask;
|
||||
delta = ((u_int64_t)tcount * tc->tc_tweak->tc_scale_nano_f);
|
||||
delta >>= 32;
|
||||
delta += ((u_int64_t)tcount * tc->tc_tweak->tc_scale_nano_i);
|
||||
hardpps(tsp, delta);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: xrpu.c,v 1.5 1998/12/14 06:32:58 dillon Exp $
|
||||
* $Id: xrpu.c,v 1.6 1999/01/12 01:42:43 eivind Exp $
|
||||
*
|
||||
* A very simple device driver for PCI cards based on Xilinx 6200 series
|
||||
* FPGA/RPU devices. Current Functionality is to allow you to open and
|
||||
@ -17,6 +17,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "opt_devfs.h"
|
||||
|
||||
#include "xrpu.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -24,7 +26,9 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/timepps.h>
|
||||
#ifdef DEFVFS
|
||||
#include <sys/devfsext.h>
|
||||
#endif
|
||||
#include <sys/xrpuio.h>
|
||||
#include <pci/pcireg.h>
|
||||
#include <pci/pcivar.h>
|
||||
@ -64,13 +68,8 @@ static struct softc {
|
||||
u_int *virbase62;
|
||||
struct timecounter tc;
|
||||
u_int *trigger, *latch, dummy;
|
||||
struct {
|
||||
pps_params_t params;
|
||||
pps_info_t info;
|
||||
int cap;
|
||||
u_int *assert, last_assert;
|
||||
u_int *clear, last_clear;
|
||||
} pps[XRPU_MAX_PPS];
|
||||
struct pps_state pps[XRPU_MAX_PPS];
|
||||
u_int *assert[XRPU_MAX_PPS], *clear[XRPU_MAX_PPS];
|
||||
} *softc[NXRPU];
|
||||
|
||||
static unsigned
|
||||
@ -90,45 +89,21 @@ xrpu_poll_pps(struct timecounter *tc)
|
||||
unsigned count1, ppscount;
|
||||
|
||||
for (i = 0; i < XRPU_MAX_PPS; i++) {
|
||||
if (sc->pps[i].assert) {
|
||||
ppscount = *(sc->pps[i].assert) & tc->tc_counter_mask;
|
||||
if (sc->assert[i]) {
|
||||
ppscount = *(sc->assert[i]) & tc->tc_counter_mask;
|
||||
do {
|
||||
count1 = ppscount;
|
||||
ppscount = *(sc->pps[i].assert) & tc->tc_counter_mask;
|
||||
ppscount = *(sc->assert[i]) & tc->tc_counter_mask;
|
||||
} while (ppscount != count1);
|
||||
if (ppscount != sc->pps[i].last_assert) {
|
||||
timecounter_timespec(ppscount, &sc->pps[i].info.assert_timestamp);
|
||||
if (sc->pps[i].params.mode & PPS_OFFSETASSERT) {
|
||||
timespecadd(&sc->pps[i].info.assert_timestamp,
|
||||
&sc->pps[i].params.assert_offset);
|
||||
if (sc->pps[i].info.assert_timestamp.tv_nsec < 0) {
|
||||
sc->pps[i].info.assert_timestamp.tv_nsec += 1000000000;
|
||||
sc->pps[i].info.assert_timestamp.tv_sec -= 1;
|
||||
}
|
||||
}
|
||||
sc->pps[i].info.assert_sequence++;
|
||||
sc->pps[i].last_assert = ppscount;
|
||||
}
|
||||
pps_event(&sc->pps[i], &sc->tc, ppscount, PPS_CAPTUREASSERT);
|
||||
}
|
||||
if (sc->pps[i].clear) {
|
||||
ppscount = *(sc->pps[i].clear) & tc->tc_counter_mask;
|
||||
if (sc->clear[i]) {
|
||||
ppscount = *(sc->clear[i]) & tc->tc_counter_mask;
|
||||
do {
|
||||
count1 = ppscount;
|
||||
ppscount = *(sc->pps[i].clear) & tc->tc_counter_mask;
|
||||
ppscount = *(sc->clear[i]) & tc->tc_counter_mask;
|
||||
} while (ppscount != count1);
|
||||
if (ppscount != sc->pps[i].last_clear) {
|
||||
timecounter_timespec(ppscount, &sc->pps[i].info.clear_timestamp);
|
||||
if (sc->pps[i].params.mode & PPS_OFFSETASSERT) {
|
||||
timespecadd(&sc->pps[i].info.clear_timestamp,
|
||||
&sc->pps[i].params.clear_offset);
|
||||
if (sc->pps[i].info.clear_timestamp.tv_nsec < 0) {
|
||||
sc->pps[i].info.clear_timestamp.tv_nsec += 1000000000;
|
||||
sc->pps[i].info.clear_timestamp.tv_sec -= 1;
|
||||
}
|
||||
}
|
||||
sc->pps[i].info.clear_sequence++;
|
||||
sc->pps[i].last_clear = ppscount;
|
||||
}
|
||||
pps_event(&sc->pps[i], &sc->tc, ppscount, PPS_CAPTURECLEAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,10 +139,7 @@ xrpu_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *pr)
|
||||
i = dev2pps(dev);
|
||||
if (i < 0 || i >= XRPU_MAX_PPS)
|
||||
return ENODEV;
|
||||
if (!sc->pps[i].cap)
|
||||
return ENODEV;
|
||||
error = std_pps_ioctl(cmd, arg, &sc->pps[i].params,
|
||||
&sc->pps[i].info, sc->pps[i].cap);
|
||||
error = pps_ioctl(cmd, arg, &sc->pps[i]);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -191,17 +163,20 @@ xrpu_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *pr)
|
||||
if (xt->xt_pps[i].xt_addr_assert == 0
|
||||
&& xt->xt_pps[i].xt_addr_clear == 0)
|
||||
continue;
|
||||
devfs_add_devswf(&xrpudevsw, (i+1)<<16, DV_CHR, UID_ROOT, GID_WHEEL, 0600,
|
||||
"xpps%d", i);
|
||||
/* DEVFS */
|
||||
#ifdef DEVFS
|
||||
devfs_add_devswf(&xrpudevsw, (i+1)<<16, DV_CHR, UID_ROOT, GID_WHEEL,
|
||||
0600, "xpps%d", i);
|
||||
#endif
|
||||
sc->pps[i].ppscap = 0;
|
||||
if (xt->xt_pps[i].xt_addr_assert) {
|
||||
sc->pps[i].assert = sc->virbase62 + xt->xt_pps[i].xt_addr_assert;
|
||||
sc->pps[i].cap |= PPS_CAPTUREASSERT | PPS_OFFSETASSERT;
|
||||
sc->assert[i] = sc->virbase62 + xt->xt_pps[i].xt_addr_assert;
|
||||
sc->pps[i].ppscap |= PPS_CAPTUREASSERT;
|
||||
}
|
||||
if (xt->xt_pps[i].xt_addr_clear) {
|
||||
sc->pps[i].clear = sc->virbase62 + xt->xt_pps[i].xt_addr_clear;
|
||||
sc->pps[i].cap |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR;
|
||||
sc->clear[i] = sc->virbase62 + xt->xt_pps[i].xt_addr_clear;
|
||||
sc->pps[i].ppscap |= PPS_CAPTURECLEAR;
|
||||
}
|
||||
pps_init(&sc->pps[i]);
|
||||
}
|
||||
sc->mode = TIMECOUNTER;
|
||||
init_timecounter(&sc->tc);
|
||||
@ -266,6 +241,8 @@ xrpu_attach (pcici_t tag, int unit)
|
||||
if (!unit)
|
||||
cdevsw_add(&cdev, &xrpudevsw, NULL);
|
||||
|
||||
#ifdef DEVFS
|
||||
devfs_add_devswf(&xrpudevsw, 0, DV_CHR, UID_ROOT, GID_WHEEL, 0600,
|
||||
"xrpu%d", unit);
|
||||
#endif
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)systm.h 8.7 (Berkeley) 3/29/95
|
||||
* $Id: systm.h,v 1.85 1999/01/28 00:57:54 dillon Exp $
|
||||
* $Id: systm.h,v 1.86 1999/03/05 19:27:22 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SYSTM_H_
|
||||
@ -160,8 +160,6 @@ void startprofclock __P((struct proc *));
|
||||
void stopprofclock __P((struct proc *));
|
||||
void setstatclockrate __P((int hzrate));
|
||||
|
||||
void hardpps __P((struct timeval *tvp, long usec));
|
||||
|
||||
char *getenv __P((char *name));
|
||||
int getenv_int __P((char *name, int *data));
|
||||
extern char *kern_envp;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)time.h 8.5 (Berkeley) 5/4/95
|
||||
* $Id: time.h,v 1.35 1998/12/15 17:38:32 des Exp $
|
||||
* $Id: time.h,v 1.36 1999/03/08 12:36:14 phk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TIME_H_
|
||||
@ -277,7 +277,6 @@ void microtime __P((struct timeval *tv));
|
||||
void nanouptime __P((struct timespec *ts));
|
||||
void nanotime __P((struct timespec *ts));
|
||||
void set_timecounter __P((struct timespec *ts));
|
||||
void timecounter_timespec __P((unsigned count, struct timespec *ts));
|
||||
void timevaladd __P((struct timeval *, struct timeval *));
|
||||
void timevalsub __P((struct timeval *, struct timeval *));
|
||||
int tvtohz __P((struct timeval *));
|
||||
|
@ -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.3 1998/06/13 09:30:24 phk Exp $
|
||||
* $Id: timepps.h,v 1.4 1998/06/22 21:09:10 phk Exp $
|
||||
*
|
||||
* The is a FreeBSD protype version of the "draft-mogul-pps-api-02.txt"
|
||||
* specification for Pulse Per Second timing interfaces.
|
||||
@ -92,8 +92,85 @@ struct pps_wait_args {
|
||||
#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));
|
||||
struct pps_state {
|
||||
pps_params_t ppsparam;
|
||||
pps_info_t ppsinfo;
|
||||
int ppscap;
|
||||
struct timecounter *ppstc;
|
||||
unsigned ppscount[3];
|
||||
};
|
||||
|
||||
#endif /* KERNEL */
|
||||
void pps_event __P((struct pps_state *pps, struct timecounter *tc, unsigned count, int event));
|
||||
void pps_init __P((struct pps_state *pps));
|
||||
int pps_ioctl __P((u_long cmd, caddr_t data, struct pps_state *pps));
|
||||
void hardpps __P((struct timespec *tsp, long nsec));
|
||||
|
||||
#else /* !KERNEL */
|
||||
|
||||
int time_pps_create(int filedes, pps_handle_t *handle);
|
||||
int time_pps_destroy(pps_handle_t handle);
|
||||
int time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams);
|
||||
int time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams);
|
||||
int time_pps_getcap(pps_handle_t handle, int *mode);
|
||||
int time_pps_fetch(pps_handle_t handle, pps_info_t *ppsinfobuf);
|
||||
int time_pps_wait(pps_handle_t handle, const struct timespec *timeout,
|
||||
pps_info_t *ppsinfobuf);
|
||||
|
||||
static __inline int
|
||||
time_pps_create(int filedes, pps_handle_t *handle)
|
||||
{
|
||||
int error;
|
||||
|
||||
*handle = -1;
|
||||
error = ioctl(filedes, PPS_IOC_CREATE, 0);
|
||||
if (error < 0)
|
||||
return (-1);
|
||||
*handle = filedes;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
time_pps_destroy(pps_handle_t handle)
|
||||
{
|
||||
return (ioctl(handle, PPS_IOC_DESTROY, 0));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams)
|
||||
{
|
||||
return (ioctl(handle, PPS_IOC_SETPARAMS, ppsparams));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams)
|
||||
{
|
||||
return (ioctl(handle, PPS_IOC_GETPARAMS, ppsparams));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
time_pps_getcap(pps_handle_t handle, int *mode)
|
||||
{
|
||||
return (ioctl(handle, PPS_IOC_GETCAP, mode));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
time_pps_fetch(pps_handle_t handle, pps_info_t *ppsinfobuf)
|
||||
{
|
||||
return (ioctl(handle, PPS_IOC_FETCH, ppsinfobuf));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
time_pps_wait(pps_handle_t handle, const struct timespec *timeout,
|
||||
pps_info_t *ppsinfobuf)
|
||||
{
|
||||
int error;
|
||||
struct pps_wait_args arg;
|
||||
|
||||
arg.timeout = *timeout;
|
||||
error = ioctl(handle, PPS_IOC_WAIT, &arg);
|
||||
*ppsinfobuf = arg.pps_info_buf;
|
||||
return (error);
|
||||
}
|
||||
|
||||
#endif /* !KERNEL */
|
||||
#endif /* _SYS_TIMEPPS_H_ */
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)time.h 8.5 (Berkeley) 5/4/95
|
||||
* $Id: time.h,v 1.35 1998/12/15 17:38:32 des Exp $
|
||||
* $Id: time.h,v 1.36 1999/03/08 12:36:14 phk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TIME_H_
|
||||
@ -277,7 +277,6 @@ void microtime __P((struct timeval *tv));
|
||||
void nanouptime __P((struct timespec *ts));
|
||||
void nanotime __P((struct timespec *ts));
|
||||
void set_timecounter __P((struct timespec *ts));
|
||||
void timecounter_timespec __P((unsigned count, struct timespec *ts));
|
||||
void timevaladd __P((struct timeval *, struct timeval *));
|
||||
void timevalsub __P((struct timeval *, struct timeval *));
|
||||
int tvtohz __P((struct timeval *));
|
||||
|
@ -59,14 +59,11 @@
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include <sys/timex.h>
|
||||
* #include <sys/syscall.h>
|
||||
*
|
||||
* int syscall(SYS_ntp_gettime, tptr);
|
||||
* int SYS_ntp_gettime;
|
||||
* struct ntptimeval *tptr;
|
||||
* int ntp_gettime(struct ntptimeval *ntv);
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The time returned by ntp_gettime() is in a timeval structure,
|
||||
* The time returned by ntp_gettime() is in a timespec structure,
|
||||
* but may be in either microsecond (seconds and microseconds) or
|
||||
* nanosecond (seconds and nanoseconds) format. The particular
|
||||
* format in use is determined by the STA_NANO bit of the status
|
||||
@ -80,6 +77,7 @@
|
||||
* #include <sys/syscall.h>
|
||||
*
|
||||
* int syscall(SYS_ntp_adjtime, tptr);
|
||||
* int SYS_ntp_adjtime;
|
||||
* struct timex *tptr;
|
||||
*
|
||||
* DESCRIPTION
|
||||
@ -89,7 +87,7 @@
|
||||
* further information.
|
||||
*/
|
||||
#ifndef _SYS_TIMEX_H_
|
||||
#define _SYS_TIMEX_H_ 1
|
||||
#define _SYS_TIMEX_H_
|
||||
|
||||
#ifndef MSDOS /* Microsoft specific */
|
||||
#include <sys/syscall.h>
|
||||
@ -171,7 +169,7 @@
|
||||
* nanoseconds if not.
|
||||
*/
|
||||
struct ntptimeval {
|
||||
struct timespec time; /* current time (ns) (ro) */
|
||||
struct timespec time; /* current time (ns/us) (ro) */
|
||||
long maxerror; /* maximum error (us) (ro) */
|
||||
long esterror; /* estimated error (us) (ro) */
|
||||
int time_state; /* time status */
|
||||
@ -214,16 +212,17 @@ struct timex {
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#ifdef KERNEL
|
||||
void ntp_update_second __P((struct timecounter *tc));
|
||||
#else
|
||||
struct timecounter;
|
||||
void ntp_update_second __P((struct timecounter *tc));
|
||||
#else /* !KERNEL */
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern int ntp_gettime __P((struct ntptimeval *));
|
||||
extern int ntp_adjtime __P((struct timex *));
|
||||
int ntp_adjtime __P((struct timex *));
|
||||
int ntp_gettime __P((struct ntptimeval *));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* not KERNEL */
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /* __FreeBSD__ */
|
||||
#endif /* _SYS_TIMEX_H_ */
|
||||
|
||||
#endif /* !_SYS_TIMEX_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user