diff --git a/ntp_io_linux.c b/ntp_io_linux.c index 3a273aa..9b53d7b 100644 --- a/ntp_io_linux.c +++ b/ntp_io_linux.c @@ -220,7 +220,7 @@ add_interface(CNF_HwTsInterface *conf_iface) SCK_CloseSocket(sock_fd); - phc_fd = SYS_Linux_OpenPHC(req.ifr_name); + phc_fd = SYS_Linux_OpenPHC(req.ifr_name, O_RDONLY); if (phc_fd < 0) return 0; diff --git a/refclock_phc.c b/refclock_phc.c index cff75d8..08da75f 100644 --- a/refclock_phc.c +++ b/refclock_phc.c @@ -66,7 +66,7 @@ static int phc_initialise(RCL_Instance instance) { const char *options[] = {"nocrossts", "extpps", "pin", "channel", "clear", NULL}; struct phc_instance *phc; - int phc_fd, rising_edge; + int rising_edge; struct stat st; char *path, *s; @@ -74,19 +74,20 @@ static int phc_initialise(RCL_Instance instance) path = RCL_GetDriverParameter(instance); - phc_fd = SYS_Linux_OpenPHC(path); - if (phc_fd < 0) - LOG_FATAL("Could not open PHC"); - phc = MallocNew(struct phc_instance); - phc->fd = phc_fd; - if (fstat(phc_fd, &st) < 0 || !S_ISCHR(st.st_mode)) - LOG_FATAL("Could not get PHC index"); - phc->dev_index = minor(st.st_rdev); phc->mode = 0; phc->nocrossts = RCL_GetDriverOption(instance, "nocrossts") ? 1 : 0; phc->extpps = RCL_GetDriverOption(instance, "extpps") ? 1 : 0; UTI_ZeroTimespec(&phc->last_extts); + + phc->fd = SYS_Linux_OpenPHC(path, phc->extpps ? O_RDWR : O_RDONLY); + if (phc->fd < 0) + LOG_FATAL("Could not open PHC"); + + if (fstat(phc->fd, &st) < 0 || !S_ISCHR(st.st_mode)) + LOG_FATAL("Could not get PHC index"); + phc->dev_index = minor(st.st_rdev); + phc->clock = HCL_CreateInstance(0, 16, UTI_Log2ToDouble(RCL_GetDriverPoll(instance)), RCL_GetPrecision(instance)); diff --git a/sys_linux.c b/sys_linux.c index febf0eb..53c49a8 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -879,7 +879,7 @@ verify_fd_is_phc(int phc_fd) /* ================================================== */ static int -open_phc_by_iface_name(const char *iface) +open_phc_by_iface_name(const char *iface, int flags) { #ifdef HAVE_LINUX_TIMESTAMPING struct ethtool_ts_info ts_info; @@ -922,7 +922,7 @@ open_phc_by_iface_name(const char *iface) "/dev/ptp%d", ts_info.phc_index) >= sizeof (phc_device)) return -1; - return open(phc_device, O_RDONLY); + return open(phc_device, flags); #else return -1; #endif @@ -931,18 +931,18 @@ open_phc_by_iface_name(const char *iface) /* ================================================== */ int -SYS_Linux_OpenPHC(const char *device) +SYS_Linux_OpenPHC(const char *device, int flags) { int phc_fd = -1; if (device[0] == '/') { - phc_fd = open(device, O_RDONLY); + phc_fd = open(device, flags); if (phc_fd >= 0) phc_fd = verify_fd_is_phc(phc_fd); } if (phc_fd < 0) { - phc_fd = open_phc_by_iface_name(device); + phc_fd = open_phc_by_iface_name(device, flags); if (phc_fd < 0) { LOG(LOGS_ERR, "Could not open PHC of iface %s : %s", device, strerror(errno)); diff --git a/sys_linux.h b/sys_linux.h index b7b3ead..b0567a8 100644 --- a/sys_linux.h +++ b/sys_linux.h @@ -39,7 +39,7 @@ extern void SYS_Linux_EnableSystemCallFilter(int level, SYS_ProcessContext conte extern int SYS_Linux_CheckKernelVersion(int req_major, int req_minor); -extern int SYS_Linux_OpenPHC(const char *device); +extern int SYS_Linux_OpenPHC(const char *device, int flags); extern int SYS_Linux_GetPHCReadings(int fd, int nocrossts, int *reading_mode, int max_readings, struct timespec tss[][3]);