From: Rodolfo Giometti <giometti@enneenne.com>
To: David Woodhouse <dwmw2@infradead.org>
Cc: linux-kernel@vger.kernel.org, Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH] LinuxPPS (with new syscalls API) - new version
Date: Tue, 3 Jul 2007 11:48:31 +0200 [thread overview]
Message-ID: <20070703094831.GA13413@enneenne.com> (raw)
In-Reply-To: <1183291392.2828.17.camel@shinybook.infradead.org>
[-- Attachment #1: Type: text/plain, Size: 711 bytes --]
On Sun, Jul 01, 2007 at 01:03:11PM +0100, David Woodhouse wrote:
>
> Seems reasonable enough in principle -- but whatever you do, don't use
> "long" for it. That would definitely need different behaviour for 32-bit
> vs. 64-bit. Use explicitly sized types such as uint32_t or uint64_t.
Here the patch to convert LinuxPPS data structs into fixed ones.
Please, take a look at it and report possible modifications.
Thanks for your time,
Rodolfo
--
GNU/Linux Solutions e-mail: giometti@enneenne.com
Linux Device Driver giometti@gnudd.com
Embedded Systems giometti@linux.it
UNIX programming phone: +39 349 2432127
[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 14151 bytes --]
diff --git a/Documentation/pps/timepps.h b/Documentation/pps/timepps.h
index d690aa6..fe8f467 100644
--- a/Documentation/pps/timepps.h
+++ b/Documentation/pps/timepps.h
@@ -28,6 +28,32 @@
/* --- 3.2 New data structures --------------------------------------------- */
+struct ntp_fp {
+ unsigned int integral;
+ unsigned int fractional;
+};
+
+union pps_timeu {
+ struct timespec tspec;
+ struct ntp_fp ntpfp;
+ unsigned long longpad[3];
+};
+
+struct pps_info {
+ unsigned long assert_sequence; /* seq. num. of assert event */
+ unsigned long clear_sequence; /* seq. num. of clear event */
+ union pps_timeu assert_tu; /* time of assert event */
+ union pps_timeu clear_tu; /* time of clear event */
+ int current_mode; /* current mode bits */
+};
+
+struct pps_params {
+ int api_version; /* API version # */
+ int mode; /* mode bits */
+ union pps_timeu assert_off_tu; /* offset compensation for assert */
+ union pps_timeu clear_off_tu; /* offset compensation for clear */
+};
+
typedef int pps_handle_t; /* represents a PPS source */
typedef unsigned long pps_seq_t; /* sequence number */
typedef struct ntp_fp ntp_fp_t; /* NTP-compatible time stamp */
@@ -86,7 +112,6 @@ void time_pps_readlink(char *link, int linklen, char *path, int pathlen)
/* Return the file name where "link" points to */
path[i] = '\0';
- return;
}
#define PPS_HAVE_FINDPATH 1
@@ -108,8 +133,10 @@ int time_pps_findpath(char *path, int pathlen, char *idstring, int idlen)
int time_pps_create(int source, pps_handle_t *handle)
{
- if (!handle)
- return -EINVAL;
+ if (!handle) {
+ errno = -EINVAL;
+ return -1;
+ }
/* In LinuxPPS there are no differences between a PPS source and
* a PPS handle so we return the same value. */
@@ -128,12 +155,33 @@ int time_pps_destroy(pps_handle_t handle)
int time_pps_getparams(pps_handle_t handle,
pps_params_t *ppsparams)
{
- return syscall(__NR_time_pps_getparams, handle, ppsparams);
+ int ret;
+ struct pps_kparams __ppsparams;
+
+ ret = syscall(__NR_time_pps_getparams, handle, &__ppsparams);
+
+ ppsparams->api_version = __ppsparams.api_version;
+ ppsparams->mode = __ppsparams.mode;
+ ppsparams->assert_off_tu.tspec.tv_sec = __ppsparams.assert_off_tu.sec;
+ ppsparams->assert_off_tu.tspec.tv_nsec = __ppsparams.assert_off_tu.nsec;
+ ppsparams->clear_off_tu.tspec.tv_sec = __ppsparams.clear_off_tu.sec;
+ ppsparams->clear_off_tu.tspec.tv_nsec = __ppsparams.clear_off_tu.nsec;
+
+ return ret;
}
int time_pps_setparams(pps_handle_t handle,
const pps_params_t *ppsparams)
{
+ struct pps_kparams __ppsparams;
+
+ __ppsparams.api_version = ppsparams->api_version;
+ __ppsparams.mode = ppsparams->mode;
+ __ppsparams.assert_off_tu.sec = ppsparams->assert_off_tu.tspec.tv_sec;
+ __ppsparams.assert_off_tu.nsec = ppsparams->assert_off_tu.tspec.tv_nsec;
+ __ppsparams.clear_off_tu.sec = ppsparams->clear_off_tu.tspec.tv_sec;
+ __ppsparams.clear_off_tu.nsec = ppsparams->clear_off_tu.tspec.tv_nsec;
+
return syscall(__NR_time_pps_getparams, handle, ppsparams);
}
@@ -147,15 +195,41 @@ int time_pps_fetch(pps_handle_t handle, const int tsformat,
pps_info_t *ppsinfobuf,
const struct timespec *timeout)
{
- return syscall(__NR_time_pps_fetch, handle,
- tsformat, ppsinfobuf, timeout);
+ struct pps_kinfo __ppsinfobuf;
+ struct pps_ktime __timeout;
+ int ret;
+
+ /* Sanity checks */
+ if (tsformat != PPS_TSFMT_TSPEC) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ if (timeout) {
+ __timeout.sec = timeout->tv_sec;
+ __timeout.nsec = timeout->tv_nsec;
+ }
+
+ ret = syscall(__NR_time_pps_fetch, handle, &__ppsinfobuf,
+ timeout ? &__timeout : NULL);
+
+ ppsinfobuf->assert_sequence = __ppsinfobuf.assert_sequence;
+ ppsinfobuf->clear_sequence = __ppsinfobuf.clear_sequence;
+ ppsinfobuf->assert_tu.tspec.tv_sec = __ppsinfobuf.assert_tu.sec;
+ ppsinfobuf->assert_tu.tspec.tv_nsec = __ppsinfobuf.assert_tu.nsec;
+ ppsinfobuf->clear_tu.tspec.tv_sec = __ppsinfobuf.clear_tu.sec;
+ ppsinfobuf->clear_tu.tspec.tv_nsec = __ppsinfobuf.clear_tu.nsec;
+ ppsinfobuf->current_mode = __ppsinfobuf.current_mode;
+
+ return ret;
}
int time_pps_kcbind(pps_handle_t handle, const int kernel_consumer,
const int edge, const int tsformat)
{
/* LinuxPPS doesn't implement kernel consumer feature */
- return -EOPNOTSUPP;
+ errno = -EOPNOTSUPP;
+ return -1;
}
#endif /* _SYS_TIMEPPS_H_ */
diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c
index dd24c31..b6ad93e 100644
--- a/drivers/pps/kapi.c
+++ b/drivers/pps/kapi.c
@@ -31,17 +31,17 @@
* Local functions
*/
-static void pps_add_offset(struct timespec *ts, struct timespec *offset)
+static void pps_add_offset(struct pps_ktime *ts, struct pps_ktime *offset)
{
- ts->tv_nsec += offset->tv_nsec;
- if (ts->tv_nsec >= NSEC_PER_SEC) {
- ts->tv_nsec -= NSEC_PER_SEC;
- ts->tv_sec++;
- } else if (ts->tv_nsec < 0) {
- ts->tv_nsec += NSEC_PER_SEC;
- ts->tv_sec--;
+ ts->nsec += offset->nsec;
+ if (ts->nsec >= NSEC_PER_SEC) {
+ ts->nsec -= NSEC_PER_SEC;
+ ts->sec++;
+ } else if (ts->nsec < 0) {
+ ts->nsec += NSEC_PER_SEC;
+ ts->sec--;
}
- ts->tv_sec += offset->tv_sec;
+ ts->sec += offset->sec;
}
/*
@@ -87,7 +87,7 @@ static int __pps_register_source(struct pps_source_info_s *info,
/* Allocate the PPS source.
*
* Note that we should reset all fields BUT "info" one! */
- memset(&(pps_source[i].params), 0, sizeof(struct pps_params));
+ memset(&(pps_source[i].params), 0, sizeof(struct pps_kparams));
pps_source[i].params.api_version = PPS_API_VERS;
pps_source[i].params.mode = default_params;
pps_source[i].assert_sequence = 0;
@@ -155,10 +155,15 @@ EXPORT_SYMBOL(pps_unregister_source);
void pps_event(int source, int event, void *data)
{
- struct timespec ts;
+ struct timespec __ts;
+ struct pps_ktime ts;
/* First of all we get the time stamp... */
- getnstimeofday(&ts);
+ getnstimeofday(&__ts);
+
+ /* ... and translate it to PPS time data struct */
+ ts.sec = __ts.tv_sec;
+ ts.nsec = __ts.tv_nsec;
if ((event & (PPS_CAPTUREASSERT|PPS_CAPTURECLEAR)) == 0 ) {
pps_err("unknow event (%x) for source %d", event, source);
@@ -175,24 +180,24 @@ void pps_event(int source, int event, void *data)
/* We have to add an offset? */
if (pps_source[source].params.mode&PPS_OFFSETASSERT)
pps_add_offset(&ts,
- &pps_source[source].params.assert_off_tu.tspec);
+ &pps_source[source].params.assert_off_tu);
/* Save the time stamp */
- pps_source[source].assert_tu.tspec = ts;
+ pps_source[source].assert_tu = ts;
pps_source[source].assert_sequence++;
- pps_dbg("capture assert seq #%lu for source %d",
+ pps_dbg("capture assert seq #%u for source %d",
pps_source[source].assert_sequence, source);
}
if (event & PPS_CAPTURECLEAR) {
/* We have to add an offset? */
if (pps_source[source].params.mode&PPS_OFFSETCLEAR)
pps_add_offset(&ts,
- &pps_source[source].params.clear_off_tu.tspec);
+ &pps_source[source].params.clear_off_tu);
/* Save the time stamp */
- pps_source[source].clear_tu.tspec = ts;
+ pps_source[source].clear_tu = ts;
pps_source[source].clear_sequence++;
- pps_dbg("capture clear seq #%lu for source %d",
+ pps_dbg("capture clear seq #%u for source %d",
pps_source[source].clear_sequence, source);
}
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c
index 428c3b7..6f56931 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -168,7 +168,7 @@ sys_time_pps_cmd_exit:
}
asmlinkage long sys_time_pps_getparams(int source,
- struct pps_params __user *params)
+ struct pps_kparams __user *params)
{
int ret = 0;
@@ -189,7 +189,7 @@ asmlinkage long sys_time_pps_getparams(int source,
/* Return current parameters */
ret = copy_to_user(params, &pps_source[source].params,
- sizeof(struct pps_params));
+ sizeof(struct pps_kparams));
if (ret)
ret = -EFAULT;
@@ -200,7 +200,7 @@ sys_time_pps_getparams_exit:
}
asmlinkage long sys_time_pps_setparams(int source,
- const struct pps_params __user *params)
+ const struct pps_kparams __user *params)
{
int ret;
@@ -233,7 +233,7 @@ asmlinkage long sys_time_pps_setparams(int source,
/* Save the new parameters */
ret = copy_from_user(&pps_source[source].params, params,
- sizeof(struct pps_params));
+ sizeof(struct pps_kparams));
if (ret) {
ret = -EFAULT;
goto sys_time_pps_setparams_exit;
@@ -282,22 +282,16 @@ sys_time_pps_getcap_exit:
return ret;
}
-asmlinkage long sys_time_pps_fetch(int source, const int tsformat,
- struct pps_info __user *info,
- const struct timespec __user *timeout)
+asmlinkage long sys_time_pps_fetch(int source, struct pps_kinfo __user *info,
+ const struct pps_ktime __user *timeout)
{
unsigned long ticks;
- struct pps_info pi;
- struct timespec to;
+ struct pps_kinfo pi;
+ struct pps_ktime to;
int ret;
pps_dbg("%s: source %d", __FUNCTION__, source);
- /* Sanity checks */
- if (tsformat != PPS_TSFMT_TSPEC) {
- pps_dbg("unsupported time format");
- return -EINVAL;
- }
if (!info)
return -EINVAL;
@@ -314,15 +308,15 @@ asmlinkage long sys_time_pps_fetch(int source, const int tsformat,
/* Manage the timeout */
if (timeout) {
- ret = copy_from_user(&to, timeout, sizeof(struct timespec));
+ ret = copy_from_user(&to, timeout, sizeof(struct pps_ktime));
if (ret) {
goto sys_time_pps_fetch_exit;
ret = -EFAULT;
}
- 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 (to.sec != -1) {
+ pps_dbg("timeout %d.%09d", to.sec, to.nsec);
+ ticks = to.sec * HZ;
+ ticks += to.nsec / (NSEC_PER_SEC / HZ);
if (ticks != 0) {
ret = wait_event_interruptible_timeout(
@@ -352,7 +346,7 @@ asmlinkage long sys_time_pps_fetch(int source, const int tsformat,
pi.assert_tu = pps_source[source].assert_tu;
pi.clear_tu = pps_source[source].clear_tu;
pi.current_mode = pps_source[source].current_mode;
- ret = copy_to_user(info, &pi, sizeof(struct pps_info));
+ ret = copy_to_user(info, &pi, sizeof(struct pps_kinfo));
if (ret)
ret = -EFAULT;
diff --git a/drivers/pps/sysfs.c b/drivers/pps/sysfs.c
index 0dae24b..46d7b7f 100644
--- a/drivers/pps/sysfs.c
+++ b/drivers/pps/sysfs.c
@@ -34,9 +34,8 @@ static ssize_t pps_show_assert(struct class_device *cdev, char *buf)
{
struct pps_s *dev = class_get_devdata(cdev);
- return sprintf(buf, "%ld.%09ld#%ld\n",
- dev->assert_tu.tspec.tv_sec,
- dev->assert_tu.tspec.tv_nsec,
+ return sprintf(buf, "%d.%09d#%d\n",
+ dev->assert_tu.sec, dev->assert_tu.nsec,
dev->assert_sequence);
}
@@ -44,9 +43,8 @@ static ssize_t pps_show_clear(struct class_device *cdev, char *buf)
{
struct pps_s *dev = class_get_devdata(cdev);
- return sprintf(buf, "%ld.%09ld#%ld\n",
- dev->clear_tu.tspec.tv_sec,
- dev->clear_tu.tspec.tv_nsec,
+ return sprintf(buf, "%d.%09d#%d\n",
+ dev->clear_tu.sec, dev->clear_tu.nsec,
dev->clear_sequence);
}
diff --git a/include/linux/pps.h b/include/linux/pps.h
index 9e3af51..001b8bf 100644
--- a/include/linux/pps.h
+++ b/include/linux/pps.h
@@ -44,30 +44,24 @@
#define PPS_MAX_NAME_LEN 32
-struct ntp_fp {
- unsigned int integral;
- unsigned int fractional;
+struct pps_ktime {
+ __u32 sec;
+ __u32 nsec;
};
-union pps_timeu {
- struct timespec tspec;
- struct ntp_fp ntpfp;
- unsigned long longpad[3];
-};
-
-struct pps_info {
- unsigned long assert_sequence; /* seq. num. of assert event */
- unsigned long clear_sequence; /* seq. num. of clear event */
- union pps_timeu assert_tu; /* time of assert event */
- union pps_timeu clear_tu; /* time of clear event */
+struct pps_kinfo {
+ __u32 assert_sequence; /* seq. num. of assert event */
+ __u32 clear_sequence; /* seq. num. of clear event */
+ struct pps_ktime assert_tu; /* time of assert event */
+ struct pps_ktime clear_tu; /* time of clear event */
int current_mode; /* current mode bits */
};
-struct pps_params {
+struct pps_kparams {
int api_version; /* API version # */
int mode; /* mode bits */
- union pps_timeu assert_off_tu; /* offset compensation for assert */
- union pps_timeu clear_off_tu; /* offset compensation for clear */
+ struct pps_ktime assert_off_tu; /* offset compensation for assert */
+ struct pps_ktime clear_off_tu; /* offset compensation for clear */
};
/*
@@ -162,12 +156,12 @@ struct pps_source_info_s {
struct pps_s {
struct pps_source_info_s *info; /* PSS source info */
- struct pps_params params; /* PPS's current params */
+ struct pps_kparams params; /* PPS's current params */
- volatile unsigned long assert_sequence; /* PPS' assert event seq # */
- volatile unsigned long clear_sequence; /* PPS' clear event seq # */
- volatile union pps_timeu assert_tu;
- volatile union pps_timeu clear_tu;
+ volatile uint32_t assert_sequence; /* PPS' assert event seq # */
+ volatile uint32_t clear_sequence; /* PPS' clear event seq # */
+ volatile struct pps_ktime assert_tu;
+ volatile struct pps_ktime clear_tu;
int current_mode; /* PPS mode at event time */
int go; /* PPS event is arrived? */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 853a21e..bfc8899 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -614,13 +614,12 @@ asmlinkage long sys_eventfd(unsigned int count);
asmlinkage long sys_time_pps_cmd(int cmd, void __user *arg);
asmlinkage long sys_time_pps_getparams(int source,
- struct pps_params __user *params);
+ struct pps_kparams __user *params);
asmlinkage long sys_time_pps_setparams(int source,
- const struct pps_params __user *params);
+ const struct pps_kparams __user *params);
asmlinkage long sys_time_pps_getcap(int source, int __user *mode);
-asmlinkage long sys_time_pps_fetch(int source, const int tsformat,
- struct pps_info __user *info,
- const struct timespec __user *timeout);
+asmlinkage long sys_time_pps_fetch(int source, struct pps_kinfo __user *info,
+ const struct pps_ktime __user *timeout);
int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
next prev parent reply other threads:[~2007-07-03 9:47 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-26 10:06 [PATCH] LinuxPPS (with new syscalls API) Rodolfo Giometti
2007-06-26 10:57 ` David Woodhouse
2007-06-26 17:06 ` Rodolfo Giometti
2007-06-26 17:38 ` David Woodhouse
2007-06-26 18:13 ` Rodolfo Giometti
2007-06-26 18:20 ` David Woodhouse
2007-06-27 10:14 ` Rodolfo Giometti
2007-06-27 10:18 ` David Woodhouse
2007-06-27 12:58 ` Rodolfo Giometti
2007-06-27 16:11 ` David Woodhouse
2007-06-27 17:45 ` Rodolfo Giometti
2007-06-27 17:49 ` David Woodhouse
2007-06-27 22:46 ` Rodolfo Giometti
2007-06-28 8:08 ` David Woodhouse
2007-06-28 8:15 ` Rodolfo Giometti
2007-06-28 8:31 ` David Woodhouse
2007-06-28 8:40 ` Rodolfo Giometti
2007-06-28 11:44 ` David Woodhouse
2007-06-28 14:15 ` Rodolfo Giometti
2007-06-28 16:14 ` [PATCH] LinuxPPS (with new syscalls API) - new version Rodolfo Giometti
2007-06-29 11:38 ` David Woodhouse
2007-06-29 15:08 ` Rodolfo Giometti
2007-06-29 15:25 ` David Woodhouse
2007-06-29 15:38 ` Rodolfo Giometti
2007-06-29 15:41 ` David Woodhouse
2007-06-29 16:23 ` Rodolfo Giometti
2007-06-29 16:23 ` David Woodhouse
2007-06-29 16:36 ` Rodolfo Giometti
2007-06-29 16:38 ` David Woodhouse
2007-06-29 15:55 ` David Woodhouse
2007-06-29 16:34 ` Rodolfo Giometti
2007-06-29 16:40 ` David Woodhouse
2007-06-30 17:13 ` Rodolfo Giometti
2007-07-01 7:13 ` Stephen Rothwell
2007-07-01 19:24 ` Rodolfo Giometti
2007-07-10 16:01 ` Lennart Sorensen
2007-07-10 16:36 ` Rodolfo Giometti
2007-07-10 16:36 ` David Woodhouse
2007-07-10 16:44 ` Rodolfo Giometti
2007-07-10 22:03 ` Lennart Sorensen
2007-07-11 8:06 ` Rodolfo Giometti
2007-07-11 15:22 ` Lennart Sorensen
2007-07-11 16:32 ` Rodolfo Giometti
2007-07-11 1:18 ` Roman Zippel
2007-07-11 15:24 ` Lennart Sorensen
2007-07-11 16:35 ` Rodolfo Giometti
2007-07-11 17:34 ` Roman Zippel
2007-07-01 12:03 ` David Woodhouse
2007-07-01 19:27 ` Rodolfo Giometti
2007-07-03 9:48 ` Rodolfo Giometti [this message]
2007-07-03 13:09 ` David Woodhouse
2007-07-03 13:21 ` Rodolfo Giometti
2007-07-09 13:19 ` Rodolfo Giometti
2007-07-10 16:05 ` David Woodhouse
2007-07-10 16:38 ` Rodolfo Giometti
2007-07-11 9:17 ` David Woodhouse
2007-07-11 10:46 ` Rodolfo Giometti
2007-06-30 8:38 ` Christoph Hellwig
2007-06-30 17:06 ` Rodolfo Giometti
2007-07-08 9:05 ` Oleg Verych
2007-07-09 9:16 ` Rodolfo Giometti
2007-07-09 10:56 ` Makefiles for GNU make (Re: [PATCH] LinuxPPS (with new syscalls API) - new version) Oleg Verych
2007-07-09 10:57 ` Rodolfo Giometti
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070703094831.GA13413@enneenne.com \
--to=giometti@enneenne.com \
--cc=akpm@linux-foundation.org \
--cc=dwmw2@infradead.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.