From 93baf34adb81046a5e1c3b9a3e685029f2046993 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Mon, 12 Nov 2018 17:27:59 +0100 Subject: [PATCH] sysoff: Extend API for different sysoff methods. The kernel supports different PTP_SYS_OFFSET* ioctls. Use the sysoff enum to allow selecting between them in sysoff_measure(). Signed-off-by: Miroslav Lichvar --- phc2sys.c | 12 ++++++------ phc_ctl.c | 8 +++++--- sysoff.c | 25 +++++++++++++++++++++---- sysoff.h | 12 +++++++----- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/phc2sys.c b/phc2sys.c index 15f8d75..2cd477a 100644 --- a/phc2sys.c +++ b/phc2sys.c @@ -74,7 +74,7 @@ struct clock { LIST_ENTRY(clock) dst_list; clockid_t clkid; int phc_index; - int sysoff_supported; + int sysoff_method; int is_utc; int dest_only; int state; @@ -255,9 +255,8 @@ static struct clock *clock_add(struct node *node, char *device) c->servo = servo_add(node, c); if (clkid != CLOCK_INVALID && clkid != CLOCK_REALTIME) - c->sysoff_supported = (SYSOFF_SUPPORTED == - sysoff_probe(CLOCKID_TO_FD(clkid), - node->phc_readings)); + c->sysoff_method = sysoff_probe(CLOCKID_TO_FD(clkid), + node->phc_readings); LIST_INSERT_HEAD(&node->clocks, c, list); return c; @@ -784,11 +783,12 @@ static int do_loop(struct node *node, int subscriptions) continue; if (clock->clkid == CLOCK_REALTIME && - node->master->sysoff_supported) { + node->master->sysoff_method >= 0) { /* use sysoff */ if (sysoff_measure(CLOCKID_TO_FD(node->master->clkid), + node->master->sysoff_method, node->phc_readings, - &offset, &ts, &delay)) + &offset, &ts, &delay) < 0) return -1; } else { /* use phc */ diff --git a/phc_ctl.c b/phc_ctl.c index 4a78a19..b9a9cf4 100644 --- a/phc_ctl.c +++ b/phc_ctl.c @@ -367,10 +367,12 @@ static int do_cmp(clockid_t clkid, int cmdc, char *cmdv[]) struct timespec ts, rta, rtb; int64_t sys_offset, delay = 0, offset; uint64_t sys_ts; + int method; - if (SYSOFF_SUPPORTED == - sysoff_measure(CLOCKID_TO_FD(clkid), - 9, &sys_offset, &sys_ts, &delay)) { + method = sysoff_probe(CLOCKID_TO_FD(clkid), 9); + + if (method >= 0 && sysoff_measure(CLOCKID_TO_FD(clkid), method, 9, + &sys_offset, &sys_ts, &delay) >= 0) { pr_notice( "offset from CLOCK_REALTIME is %"PRId64"ns\n", sys_offset); return 0; diff --git a/sysoff.c b/sysoff.c index 407a01c..f709a9b 100644 --- a/sysoff.c +++ b/sysoff.c @@ -73,8 +73,8 @@ static int64_t sysoff_estimate(struct ptp_clock_time *pct, int n_samples, return samples[0].offset; } -int sysoff_measure(int fd, int n_samples, - int64_t *result, uint64_t *ts, int64_t *delay) +static int sysoff_basic(int fd, int n_samples, + int64_t *result, uint64_t *ts, int64_t *delay) { struct ptp_sys_offset pso; memset(&pso, 0, sizeof(pso)); @@ -84,13 +84,24 @@ int sysoff_measure(int fd, int n_samples, return SYSOFF_RUN_TIME_MISSING; } *result = sysoff_estimate(pso.ts, n_samples, ts, delay); - return SYSOFF_SUPPORTED; + return SYSOFF_BASIC; +} + +int sysoff_measure(int fd, int method, int n_samples, + int64_t *result, uint64_t *ts, int64_t *delay) +{ + switch (method) { + case SYSOFF_BASIC: + return sysoff_basic(fd, n_samples, result, ts, delay); + } + return SYSOFF_COMPILE_TIME_MISSING; } int sysoff_probe(int fd, int n_samples) { int64_t junk, delay; uint64_t ts; + int i; if (n_samples > PTP_MAX_SAMPLES) { fprintf(stderr, "warning: %d exceeds kernel max readings %d\n", @@ -99,7 +110,13 @@ int sysoff_probe(int fd, int n_samples) return SYSOFF_RUN_TIME_MISSING; } - return sysoff_measure(fd, n_samples, &junk, &ts, &delay); + for (i = 0; i < SYSOFF_LAST; i++) { + if (sysoff_measure(fd, i, n_samples, &junk, &ts, &delay) < 0) + continue; + return i; + } + + return SYSOFF_RUN_TIME_MISSING; } #else /* !PTP_SYS_OFFSET */ diff --git a/sysoff.h b/sysoff.h index cb70265..02ecdfa 100644 --- a/sysoff.h +++ b/sysoff.h @@ -21,13 +21,14 @@ #include enum { - SYSOFF_SUPPORTED, - SYSOFF_COMPILE_TIME_MISSING, - SYSOFF_RUN_TIME_MISSING, + SYSOFF_COMPILE_TIME_MISSING = -2, + SYSOFF_RUN_TIME_MISSING = -1, + SYSOFF_BASIC, + SYSOFF_LAST, }; /** - * Check to see if the PTP_SYS_OFFSET ioctl is supported. + * Check to see if a PTP_SYS_OFFSET ioctl is supported. * @param fd An open file descriptor to a PHC device. * @return One of the SYSOFF_ enumeration values. */ @@ -36,11 +37,12 @@ int sysoff_probe(int fd, int n_samples); /** * Measure the offset between a PHC and the system time. * @param fd An open file descriptor to a PHC device. + * @param method A non-negative SYSOFF_ value returned by sysoff_probe(). * @param n_samples The number of consecutive readings to make. * @param result The estimated offset in nanoseconds. * @param ts The system time corresponding to the 'result'. * @param delay The delay in reading of the clock in nanoseconds. * @return One of the SYSOFF_ enumeration values. */ -int sysoff_measure(int fd, int n_samples, +int sysoff_measure(int fd, int method, int n_samples, int64_t *result, uint64_t *ts, int64_t *delay);