diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index befe292..820cc9a 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -284,13 +285,12 @@ sys_time_pps_getcap_exit: return ret; } -asmlinkage long sys_time_pps_fetch(int source, const int tsformat, +static long __sys_time_pps_fetch(int source, const int tsformat, struct pps_info __user *info, - const struct timespec __user *timeout) + const struct timespec *timeout) { unsigned long ticks; struct pps_info pi; - struct timespec to; int ret; pps_dbg("%s: source %d", __FUNCTION__, source); @@ -317,24 +317,19 @@ asmlinkage long sys_time_pps_fetch(int source, const int tsformat, pps_source[source].go = 0; /* Manage the timeout */ - if (timeout) { - ret = copy_from_user(&to, timeout, sizeof(struct timespec)); - if (ret) - goto sys_time_pps_fetch_exit; - if (to.tv_sec != -1) { - pps_dbg("timeout %ld.%09ld", to.tv_sec, to.tv_nsec); - ticks = to.tv_sec * HZ; - ticks += to.tv_nsec / (NSEC_PER_SEC / HZ); - - if (ticks != 0) { - ret = wait_event_interruptible_timeout( - pps_source[source].queue, - pps_source[source].go, ticks); - if (ret == 0) { - pps_dbg("timeout expired"); - ret = -ETIMEDOUT; - goto sys_time_pps_fetch_exit; - } + if (timeout->tv_sec != -1) { + pps_dbg("timeout %ld.%09ld", timeout->tv_sec, timeout->tv_nsec); + ticks = timeout->tv_sec * HZ; + ticks += timeout->tv_nsec / (NSEC_PER_SEC / HZ); + + if (ticks != 0) { + ret = wait_event_interruptible_timeout( + pps_source[source].queue, + pps_source[source].go, ticks); + if (ret == 0) { + pps_dbg("timeout expired"); + ret = -ETIMEDOUT; + goto sys_time_pps_fetch_exit; } } } else @@ -362,6 +357,44 @@ sys_time_pps_fetch_exit: return ret; } +asmlinkage long sys_time_pps_fetch(int source, const int tsformat, + struct pps_info __user *info, + const struct timespec __user *timeout) +{ + int ret; + struct timespec to; + + if (timeout) { + ret = copy_from_user(&to, timeout, sizeof(struct timespec)); + if (ret) + return ret; + } + else + to.tv_sec = -1; + + return __sys_time_pps_fetch(source, tsformat, info, timeout); +} + +#ifdef CONFIG_COMPAT +asmlinkage long compat_sys_time_pps_fetch(int source, const int tsformat, + struct pps_info __user *info, + const struct compat_timespec __user *timeout) +{ + int ret; + struct timespec to; + + if (timeout) { + ret = get_compat_timespec(&to, timeout); + if (ret) + return -EFAULT; + } + else + to.tv_sec = -1; + + return __sys_time_pps_fetch(source, tsformat, info, &to); +} +#endif + /* * Module staff */