phc2sys: open devices in clock_add

Do not call clock_open to open a clock device but let clock_add do that and
return the newly created struct. Also, store the device (interface) name in
struct clock.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
master
Jiri Benc 2014-06-11 21:35:16 +02:00 committed by Richard Cochran
parent b826ce530b
commit 90bbdbcfae
1 changed files with 47 additions and 36 deletions

View File

@ -67,6 +67,7 @@ struct clock {
int is_utc; int is_utc;
struct servo *servo; struct servo *servo;
enum servo_state servo_state; enum servo_state servo_state;
char *device;
const char *source_label; const char *source_label;
struct stats *offset_stats; struct stats *offset_stats;
struct stats *freq_stats; struct stats *freq_stats;
@ -129,19 +130,27 @@ static clockid_t clock_open(char *device)
return clkid; return clkid;
} }
static int clock_add(struct node *node, clockid_t clkid) static struct clock *clock_add(struct node *node, char *device)
{ {
struct clock *c; struct clock *c;
clockid_t clkid = CLOCK_INVALID;
int max_ppb; int max_ppb;
double ppb; double ppb;
if (device) {
clkid = clock_open(device);
if (clkid == CLOCK_INVALID)
return NULL;
}
c = calloc(1, sizeof(*c)); c = calloc(1, sizeof(*c));
if (!c) { if (!c) {
pr_err("failed to allocate memory for a clock"); pr_err("failed to allocate memory for a clock");
return -1; return NULL;
} }
c->clkid = clkid; c->clkid = clkid;
c->servo_state = SERVO_UNLOCKED; c->servo_state = SERVO_UNLOCKED;
c->device = strdup(device);
if (c->clkid == CLOCK_REALTIME) { if (c->clkid == CLOCK_REALTIME) {
c->source_label = "sys"; c->source_label = "sys";
@ -158,14 +167,14 @@ static int clock_add(struct node *node, clockid_t clkid)
!c->freq_stats || !c->freq_stats ||
!c->delay_stats) { !c->delay_stats) {
pr_err("failed to create stats"); pr_err("failed to create stats");
return -1; return NULL;
} }
} }
if (node->sanity_freq_limit) { if (node->sanity_freq_limit) {
c->sanity_check = clockcheck_create(node->sanity_freq_limit); c->sanity_check = clockcheck_create(node->sanity_freq_limit);
if (!c->sanity_check) { if (!c->sanity_check) {
pr_err("failed to create clock check"); pr_err("failed to create clock check");
return -1; return NULL;
} }
} }
@ -181,7 +190,7 @@ static int clock_add(struct node *node, clockid_t clkid)
max_ppb = phc_max_adj(c->clkid); max_ppb = phc_max_adj(c->clkid);
if (!max_ppb) { if (!max_ppb) {
pr_err("clock is not adjustable"); pr_err("clock is not adjustable");
return -1; return NULL;
} }
} }
@ -194,7 +203,7 @@ static int clock_add(struct node *node, clockid_t clkid)
node->phc_readings)); node->phc_readings));
LIST_INSERT_HEAD(&node->clocks, c, list); LIST_INSERT_HEAD(&node->clocks, c, list);
return 0; return c;
} }
static int read_phc(clockid_t clkid, clockid_t sysclk, int readings, static int read_phc(clockid_t clkid, clockid_t sysclk, int readings,
@ -699,8 +708,8 @@ static void usage(char *progname)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *progname; char *progname;
clockid_t src = CLOCK_INVALID; char *src_name = NULL, *dst_name = NULL;
clockid_t dst = CLOCK_REALTIME; struct clock *src, *dst;
int c, domain_number = 0, pps_fd = -1; int c, domain_number = 0, pps_fd = -1;
int r, wait_sync = 0; int r, wait_sync = 0;
int print_level = LOG_INFO, use_syslog = 1, verbose = 0; int print_level = LOG_INFO, use_syslog = 1, verbose = 0;
@ -723,7 +732,7 @@ int main(int argc, char *argv[])
"c:d:s:E:P:I:S:F:R:N:O:L:i:u:wn:xl:mqvh"))) { "c:d:s:E:P:I:S:F:R:N:O:L:i:u:wn:xl:mqvh"))) {
switch (c) { switch (c) {
case 'c': case 'c':
dst = clock_open(optarg); dst_name = strdup(optarg);
break; break;
case 'd': case 'd':
pps_fd = open(optarg, O_RDONLY); pps_fd = open(optarg, O_RDONLY);
@ -737,7 +746,7 @@ int main(int argc, char *argv[])
fprintf(stderr, fprintf(stderr,
"'-i' has been deprecated. please use '-s' instead.\n"); "'-i' has been deprecated. please use '-s' instead.\n");
case 's': case 's':
src = clock_open(optarg); src_name = strdup(optarg);
break; break;
case 'E': case 'E':
if (!strcasecmp(optarg, "pi")) { if (!strcasecmp(optarg, "pi")) {
@ -826,24 +835,12 @@ int main(int argc, char *argv[])
} }
} }
if (pps_fd < 0 && src == CLOCK_INVALID) { if (pps_fd < 0 && !src_name) {
fprintf(stderr, fprintf(stderr,
"valid source clock must be selected.\n"); "valid source clock must be selected.\n");
goto bad_usage; goto bad_usage;
} }
if (dst == CLOCK_INVALID) {
fprintf(stderr,
"valid destination clock must be selected.\n");
goto bad_usage;
}
if (pps_fd >= 0 && dst != CLOCK_REALTIME) {
fprintf(stderr,
"cannot use a pps device unless destination is CLOCK_REALTIME\n");
goto bad_usage;
}
if (!wait_sync && !node.forced_sync_offset) { if (!wait_sync && !node.forced_sync_offset) {
fprintf(stderr, fprintf(stderr,
"time offset must be specified using -w or -O\n"); "time offset must be specified using -w or -O\n");
@ -855,9 +852,29 @@ int main(int argc, char *argv[])
print_set_syslog(use_syslog); print_set_syslog(use_syslog);
print_set_level(print_level); print_set_level(print_level);
clock_add(&node, src); src = clock_add(&node, src_name);
node.master = LIST_FIRST(&node.clocks); free(src_name);
clock_add(&node, dst); node.master = src;
dst = clock_add(&node, dst_name ? dst_name : "CLOCK_REALTIME");
free(dst_name);
if (!dst) {
fprintf(stderr,
"valid destination clock must be selected.\n");
goto bad_usage;
}
if (!src) {
fprintf(stderr,
"valid source clock must be selected.\n");
goto bad_usage;
}
if (pps_fd >= 0 && dst->clkid != CLOCK_REALTIME) {
fprintf(stderr,
"cannot use a pps device unless destination is CLOCK_REALTIME\n");
goto bad_usage;
}
if (wait_sync) { if (wait_sync) {
if (init_pmc(&node, domain_number)) if (init_pmc(&node, domain_number))
@ -882,22 +899,16 @@ int main(int argc, char *argv[])
} }
if (node.forced_sync_offset || if (node.forced_sync_offset ||
(src != CLOCK_REALTIME && dst != CLOCK_REALTIME) || (src->clkid != CLOCK_REALTIME && dst->clkid != CLOCK_REALTIME) ||
src == CLOCK_INVALID) src->clkid == CLOCK_INVALID)
close_pmc(&node); close_pmc(&node);
} }
if (pps_fd >= 0) { if (pps_fd >= 0) {
/* only one destination clock allowed with PPS until we /* only one destination clock allowed with PPS until we
* implement a mean to specify PTP port to PPS mapping */ * implement a mean to specify PTP port to PPS mapping */
struct clock *dst_clock; servo_sync_interval(dst->servo, 1.0);
return do_pps_loop(&node, dst, pps_fd);
LIST_FOREACH(dst_clock, &node.clocks, list) {
if (dst_clock != node.master)
break;
}
servo_sync_interval(dst_clock->servo, 1.0);
return do_pps_loop(&node, dst_clock, pps_fd);
} }
return do_loop(&node); return do_loop(&node);