From: Pieter Palmers <[EMAIL PROTECTED]> This implements the simultaneous read of the isochronous cycle timer and the system clock (in usecs). This allows to express the exact receive time of an ISO packet as a system time with microsecond accuracy. http://bugzilla.kernel.org/show_bug.cgi?id=7773
The counterpart patch for libraw1394 can be found at http://thread.gmane.org/gmane.linux.kernel.firewire.devel/8934 Patch update (Stefan R.): - Disable preemption and local interrupts. - Fix integer overflow. - Add paranoid error checks and kerneldoc to hpsb_read_cycle_timer. Move it to other ieee1394_core high-level API functions. - Rename userspace-exported struct _raw1394_cycle_timer to raw1394_cycle_timer. Change comments in raw1394. - Adjust whitespace. Signed-off-by: Stefan Richter <[EMAIL PROTECTED]> --- Pieter, Dan, is this OK? I only compile-tested. drivers/ieee1394/ieee1394-ioctl.h | 2 + drivers/ieee1394/ieee1394_core.c | 43 ++++++++++++++++++++++++++++++ drivers/ieee1394/ieee1394_core.h | 3 ++ drivers/ieee1394/raw1394.c | 20 +++++++++++++ drivers/ieee1394/raw1394.h | 10 ++++++ 5 files changed, 78 insertions(+) Index: linux/drivers/ieee1394/ieee1394-ioctl.h =================================================================== --- linux.orig/drivers/ieee1394/ieee1394-ioctl.h 2007-01-01 01:53:20.000000000 +0100 +++ linux/drivers/ieee1394/ieee1394-ioctl.h 2007-02-03 13:47:33.000000000 +0100 @@ -100,5 +100,7 @@ _IO ('#', 0x28) #define RAW1394_IOC_ISO_RECV_FLUSH \ _IO ('#', 0x29) +#define RAW1394_IOC_GET_CYCLE_TIMER \ + _IOR ('#', 0x30, struct raw1394_cycle_timer) #endif /* __IEEE1394_IOCTL_H */ Index: linux/drivers/ieee1394/ieee1394_core.c =================================================================== --- linux.orig/drivers/ieee1394/ieee1394_core.c 2007-01-27 14:07:00.000000000 +0100 +++ linux/drivers/ieee1394/ieee1394_core.c 2007-02-03 13:47:33.000000000 +0100 @@ -33,6 +33,9 @@ #include <linux/skbuff.h> #include <linux/suspend.h> #include <linux/kthread.h> +#include <linux/irqflags.h> +#include <linux/preempt.h> +#include <linux/time.h> #include <asm/byteorder.h> @@ -186,6 +189,45 @@ int hpsb_reset_bus(struct hpsb_host *hos } } +/** + * hpsb_read_cycle_timer - read cycle timer register and system time + * @host: host whose isochronous cycle timer register is read + * @cycle_timer: address of bitfield to return the register contents + * @local_time: address to return the system time + * + * The format of * @cycle_timer, is described in OHCI 1.1 clause 5.13. This + * format is also read from non-OHCI controllers. * @local_time contains the + * system time in microseconds since the Epoch, read at the moment when the + * cycle timer was read. + * + * Return value: 0 for success or error number otherwise. + */ +int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer, + u64 *local_time) +{ + int ctr; + struct timeval tv; + unsigned long flags; + + if (!host || !cycle_timer || !local_time) + return -EINVAL; + + preempt_disable(); + local_irq_save(flags); + + ctr = host->driver->devctl(host, GET_CYCLE_COUNTER, 0); + if (ctr) + do_gettimeofday(&tv); + + local_irq_restore(flags); + preempt_enable(); + + if (!ctr) + return -EIO; + *cycle_timer = ctr; + *local_time = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; + return 0; +} int hpsb_bus_reset(struct hpsb_host *host) { @@ -1190,6 +1232,7 @@ EXPORT_SYMBOL(hpsb_alloc_packet); EXPORT_SYMBOL(hpsb_free_packet); EXPORT_SYMBOL(hpsb_send_packet); EXPORT_SYMBOL(hpsb_reset_bus); +EXPORT_SYMBOL(hpsb_read_cycle_timer); EXPORT_SYMBOL(hpsb_bus_reset); EXPORT_SYMBOL(hpsb_selfid_received); EXPORT_SYMBOL(hpsb_selfid_complete); Index: linux/drivers/ieee1394/ieee1394_core.h =================================================================== --- linux.orig/drivers/ieee1394/ieee1394_core.h 2007-01-01 01:53:20.000000000 +0100 +++ linux/drivers/ieee1394/ieee1394_core.h 2007-02-03 13:47:33.000000000 +0100 @@ -127,6 +127,9 @@ int hpsb_send_packet_and_wait(struct hps * progress, 0 otherwise. */ int hpsb_reset_bus(struct hpsb_host *host, int type); +int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer, + u64 *local_time); + /* * The following functions are exported for host driver module usage. All of * them are safe to use in interrupt contexts, although some are quite Index: linux/drivers/ieee1394/raw1394.c =================================================================== --- linux.orig/drivers/ieee1394/raw1394.c 2007-01-27 14:07:00.000000000 +0100 +++ linux/drivers/ieee1394/raw1394.c 2007-02-03 13:47:34.000000000 +0100 @@ -2664,6 +2664,18 @@ static void raw1394_iso_shutdown(struct fi->iso_state = RAW1394_ISO_INACTIVE; } +static int raw1394_read_cycle_timer(struct file_info *fi, void __user * uaddr) +{ + struct raw1394_cycle_timer ct; + int err; + + err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time); + if (!err) + if (copy_to_user(uaddr, &ct, sizeof(ct))) + err = -EFAULT; + return err; +} + /* mmap the rawiso xmit/recv buffer */ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma) { @@ -2772,6 +2784,14 @@ static int raw1394_ioctl(struct inode *i break; } + /* state-independent commands */ + switch(cmd) { + case RAW1394_IOC_GET_CYCLE_TIMER: + return raw1394_read_cycle_timer(fi, argp); + default: + break; + } + return -EINVAL; } Index: linux/drivers/ieee1394/raw1394.h =================================================================== --- linux.orig/drivers/ieee1394/raw1394.h 2007-01-01 01:53:20.000000000 +0100 +++ linux/drivers/ieee1394/raw1394.h 2007-02-03 13:47:34.000000000 +0100 @@ -178,4 +178,14 @@ struct raw1394_iso_status { __s16 xmit_cycle; }; +/* argument to RAW1394_IOC_GET_CYCLE_TIMER ioctl */ +struct raw1394_cycle_timer { + /* contents of Isochronous Cycle Timer register, + as in OHCI 1.1 clause 5.13 (also with non-OHCI hosts) */ + __u32 cycle_timer; + + /* local time in microseconds since Epoch, + simultaneously read with cycle timer */ + __u64 local_time; +}; #endif /* IEEE1394_RAW1394_H */ -- Stefan Richter -=====-=-=== --=- ---== http://arcgraph.de/sr/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/