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: Mon, 9 Jul 2007 15:19:24 +0200 [thread overview]
Message-ID: <20070709131924.GM11451@enneenne.com> (raw)
In-Reply-To: <1183468191.29081.17.camel@shinybook.infradead.org>
[-- Attachment #1: Type: text/plain, Size: 1167 bytes --]
On Tue, Jul 03, 2007 at 09:09:50AM -0400, David Woodhouse wrote:
>
> Looks relatively sane at first glance; busy this week so haven't looked
> very hard yet. Two thing though... you're mixing proper C types
> (uint32_t) and the Linux-specific legacy crap types (__u32). Pick one. I
> won't recommend _which_ one, because if I do I'll make Andrew unhappy.
> But pick one; don't use both at the same time.
Ok. I choose __u32. :)
> Also read Documentation/volatile-considered-harmful.txt and ponder
> deeply your use of 'volatile' on certain members of struct pps_s.
I read such document but I'm still convinced that the attribute
volatile is needed for {assert,clear}_sequence and {assert,clear}_tu
since inside pps_event() they are updated without any locks at all
thanks to the dummy_info variable which is used for unallocated PPS
sources.
Here you can find my last patch.
Thanks again,
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: 13980 bytes --]
diff --git a/Documentation/pps/Makefile b/Documentation/pps/Makefile
diff --git a/Documentation/pps/timepps.h b/Documentation/pps/timepps.h
index a7719eb..0427ee0 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 */
@@ -129,13 +155,34 @@ 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)
{
- return syscall(__NR_time_pps_getparams, handle, 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);
}
/* Get capabilities for handle */
@@ -148,8 +195,33 @@ 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,
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..3545c58 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,25 +308,23 @@ 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 (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;
- }
+ 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(
+ 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
@@ -352,7 +344,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..05397cd 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 __u32 assert_sequence; /* PPS' assert event seq # */
+ volatile __u32 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-09 13:18 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
2007-07-03 13:09 ` David Woodhouse
2007-07-03 13:21 ` Rodolfo Giometti
2007-07-09 13:19 ` Rodolfo Giometti [this message]
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=20070709131924.GM11451@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.