From 3dc5ea9b31a8c83cffa338aba91adbc9bd387002 Mon Sep 17 00:00:00 2001 From: Pieter Palmers Date: Sat, 3 Feb 2007 17:44:39 +0100 Subject: ieee1394: cycle timer read extension for raw1394 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. Prevent integer overflow. Add paranoid error checks and kerneldoc to hpsb_read_cycle_timer. Move it to other ieee1394_core high-level API functions. Change comments. Adjust whitespace. Rename struct _raw1394_cycle_timer. Signed-off-by: Stefan Richter Acked-by: Pieter Palmers Acked-by: Dan Dennedy --- drivers/ieee1394/ieee1394_core.c | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers/ieee1394/ieee1394_core.c') diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 1521e57e124..d791d08c743 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -33,7 +33,10 @@ #include #include #include +#include +#include +#include #include #include "ieee1394_types.h" @@ -186,6 +189,45 @@ int hpsb_reset_bus(struct hpsb_host *host, int type) } } +/** + * 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 * 1000000ULL + 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); -- cgit v1.2.3