Simplify the RFC2783 and PPS_SYNC timestamp collection API.

This commit is contained in:
Poul-Henning Kamp 2002-04-26 20:24:28 +00:00
parent 79dea31b97
commit 7bf758bff0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=95523
7 changed files with 71 additions and 61 deletions

View file

@ -21,7 +21,6 @@
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/timetc.h>
#include <sys/timepps.h>
#include <machine/bus.h>
#include <machine/resource.h>
@ -258,8 +257,6 @@ ppshcpoll(void *arg)
{
struct pps_data *sc = arg;
int i, j, k, l;
struct timecounter *tc;
unsigned count;
if (!(sc->busy & ~1))
return;
@ -267,16 +264,14 @@ ppshcpoll(void *arg)
i = ppb_rdtr(sc->ppbus);
if (i == sc->lastdata)
return;
tc = timecounter;
count = timecounter->tc_get_timecount(tc);
l = sc->lastdata ^ i;
k = 1;
for (j = 1; j < 9; j ++) {
if (l & k)
pps_event(&sc->pps[j], tc, count,
i & k ?
PPS_CAPTUREASSERT : PPS_CAPTURECLEAR
);
if (l & k) {
pps_capture(&sc->pps[j]);
pps_event(&sc->pps[j],
i & k ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR);
}
k += k;
}
sc->lastdata = i;
@ -288,16 +283,13 @@ ppsintr(void *arg)
device_t ppsdev = (device_t)arg;
struct pps_data *sc = DEVTOSOFTC(ppsdev);
device_t ppbus = sc->ppbus;
struct timecounter *tc;
unsigned count;
tc = timecounter;
count = timecounter->tc_get_timecount(tc);
pps_capture(&sc->pps[0]);
if (!(ppb_rstr(ppbus) & nACK))
return;
if (sc->pps[0].ppsparam.mode & PPS_ECHOASSERT)
ppb_wctr(ppbus, IRQENABLE | AUTOFEED);
pps_event(&sc->pps[0], tc, count, PPS_CAPTUREASSERT);
pps_event(&sc->pps[0], PPS_CAPTUREASSERT);
if (sc->pps[0].ppsparam.mode & PPS_ECHOASSERT)
ppb_wctr(ppbus, IRQENABLE);
}

View file

@ -69,7 +69,6 @@
#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/timetc.h>
#include <sys/timepps.h>
#include <sys/uio.h>
@ -1725,8 +1724,6 @@ siointr1(com)
u_char recv_data;
u_char int_ctl;
u_char int_ctl_new;
struct timecounter *tc;
u_int count;
int_ctl = inb(com->intr_ctl_port);
int_ctl_new = int_ctl;
@ -1735,10 +1732,8 @@ siointr1(com)
if (com->pps.ppsparam.mode & PPS_CAPTUREBOTH) {
modem_status = inb(com->modem_status_port);
if ((modem_status ^ com->last_modem_status) & MSR_DCD) {
tc = timecounter;
count = tc->tc_get_timecount(tc);
pps_event(&com->pps, tc, count,
(modem_status & MSR_DCD) ?
pps_capture(&com->pps);
pps_event(&com->pps, (modem_status & MSR_DCD) ?
PPS_CAPTUREASSERT : PPS_CAPTURECLEAR);
}
}

View file

@ -478,7 +478,18 @@ pps_init(struct pps_state *pps)
}
void
pps_event(struct pps_state *pps, struct timecounter *tc, unsigned count, int event)
pps_capture(struct pps_state *pps)
{
struct timecounter *tc;
tc = timecounter;
pps->captc = tc;
pps->capgen = tc->tc_generation;
pps->capcount = tc->tc_get_timecount(tc);
}
void
pps_event(struct pps_state *pps, int event)
{
struct timespec ts, *tsp, *osp;
unsigned tcount, *pcount;
@ -486,6 +497,10 @@ pps_event(struct pps_state *pps, struct timecounter *tc, unsigned count, int eve
int foff, fhard;
pps_seq_t *pseq;
/* If the timecounter were wound up, bail. */
if (pps->capgen != pps->capgen)
return;
/* Things would be easier with arrays... */
if (event == PPS_CAPTUREASSERT) {
tsp = &pps->ppsinfo.assert_timestamp;
@ -505,26 +520,32 @@ pps_event(struct pps_state *pps, struct timecounter *tc, unsigned count, int eve
/* 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;
pps->ppstc->tc_name != pps->captc->tc_name ||
pps->captc->tc_name != timecounter->tc_name) {
pps->ppstc = pps->captc;
*pcount = pps->capcount;
#ifdef PPS_SYNC
pps->ppscount[2] = pps->capcount;
#endif
return;
}
/* Nothing really happened */
if (*pcount == count)
if (*pcount == pps->capcount)
return;
*pcount = count;
/* Convert the count to timespec */
tcount = count - tc->tc_offset_count;
tcount &= tc->tc_counter_mask;
bt = tc->tc_offset;
bintime_addx(&bt, tc->tc_scale * tcount);
tcount = pps->capcount - pps->captc->tc_offset_count;
tcount &= pps->captc->tc_counter_mask;
bt = pps->captc->tc_offset;
bintime_addx(&bt, pps->captc->tc_scale * tcount);
bintime2timespec(&bt, &ts);
/* If the timecounter were wound up, bail. */
if (pps->capgen != pps->capgen)
return;
*pcount = pps->capcount;
(*pseq)++;
*tsp = ts;
@ -538,12 +559,12 @@ pps_event(struct pps_state *pps, struct timecounter *tc, unsigned count, int eve
#ifdef PPS_SYNC
if (fhard) {
/* magic, at its best... */
tcount = count - pps->ppscount[2];
pps->ppscount[2] = count;
tcount &= tc->tc_counter_mask;
tcount = pps->capcount - pps->ppscount[2];
pps->ppscount[2] = pps->capcount;
tcount &= pps->captc->tc_counter_mask;
bt.sec = 0;
bt.frac = 0;
bintime_addx(&bt, tc->tc_scale * tcount);
bintime_addx(&bt, pps->captc->tc_scale * tcount);
bintime2timespec(&bt, &ts);
hardpps(tsp, ts.tv_nsec + 1000000000 * ts.tv_sec);
}

View file

@ -131,7 +131,6 @@
#include <sys/tty.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/timetc.h>
#include <sys/timepps.h>
#include <sys/uio.h>
@ -2568,8 +2567,6 @@ siointr1(com)
u_char recv_data;
u_char int_ctl;
u_char int_ctl_new;
struct timecounter *tc;
u_int count;
#ifdef PC98
u_char tmp = 0;
@ -2611,10 +2608,8 @@ status_read:;
if (com->pps.ppsparam.mode & PPS_CAPTUREBOTH) {
modem_status = inb(com->modem_status_port);
if ((modem_status ^ com->last_modem_status) & MSR_DCD) {
tc = timecounter;
count = tc->tc_get_timecount(tc);
pps_event(&com->pps, tc, count,
(modem_status & MSR_DCD) ?
pps_capture(&com->pps);
pps_event(&com->pps, (modem_status & MSR_DCD) ?
PPS_CAPTUREASSERT : PPS_CAPTURECLEAR);
}
}

View file

@ -131,7 +131,6 @@
#include <sys/tty.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/timetc.h>
#include <sys/timepps.h>
#include <sys/uio.h>
@ -2568,8 +2567,6 @@ siointr1(com)
u_char recv_data;
u_char int_ctl;
u_char int_ctl_new;
struct timecounter *tc;
u_int count;
#ifdef PC98
u_char tmp = 0;
@ -2611,10 +2608,8 @@ status_read:;
if (com->pps.ppsparam.mode & PPS_CAPTUREBOTH) {
modem_status = inb(com->modem_status_port);
if ((modem_status ^ com->last_modem_status) & MSR_DCD) {
tc = timecounter;
count = tc->tc_get_timecount(tc);
pps_event(&com->pps, tc, count,
(modem_status & MSR_DCD) ?
pps_capture(&com->pps);
pps_event(&com->pps, (modem_status & MSR_DCD) ?
PPS_CAPTUREASSERT : PPS_CAPTURECLEAR);
}
}

View file

@ -94,22 +94,28 @@ xrpu_poll_pps(struct timecounter *tc)
for (i = 0; i < XRPU_MAX_PPS; i++) {
if (sc->assert[i]) {
sc->pps[i].capgen = tc->tc_generation;
ppscount = *(sc->assert[i]) & tc->tc_counter_mask;
j = 0;
do {
count1 = ppscount;
ppscount = *(sc->assert[i]) & tc->tc_counter_mask;
} while (ppscount != count1 && ++j < 5);
pps_event(&sc->pps[i], tc, ppscount, PPS_CAPTUREASSERT);
sc->pps[i].captc = tc;
sc->pps[i].capcount = ppscount;
pps_event(&sc->pps[i], PPS_CAPTUREASSERT);
}
if (sc->clear[i]) {
sc->pps[i].capgen = tc->tc_generation;
j = 0;
ppscount = *(sc->clear[i]) & tc->tc_counter_mask;
do {
count1 = ppscount;
ppscount = *(sc->clear[i]) & tc->tc_counter_mask;
} while (ppscount != count1 && ++j < 5);
pps_event(&sc->pps[i], tc, ppscount, PPS_CAPTURECLEAR);
sc->pps[i].captc = tc;
sc->pps[i].capcount = ppscount;
pps_event(&sc->pps[i], PPS_CAPTURECLEAR);
}
}
}

View file

@ -104,6 +104,11 @@ struct pps_kcbind_args {
#ifdef _KERNEL
struct pps_state {
/* capture information */
struct timecounter *captc;
u_int capgen;
u_int capcount;
/* state information */
pps_params_t ppsparam;
pps_info_t ppsinfo;
int kcmode;
@ -112,7 +117,8 @@ struct pps_state {
unsigned ppscount[3];
};
void pps_event(struct pps_state *pps, struct timecounter *tc, unsigned count, int event);
void pps_capture(struct pps_state *pps);
void pps_event(struct pps_state *pps, int event);
void pps_init(struct pps_state *pps);
int pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps);
void hardpps(struct timespec *tsp, long nsec);