aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/ieee1394_core.c
diff options
context:
space:
mode:
authorPieter Palmers <pieterp@joow.be>2007-02-03 11:44:39 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2007-02-17 08:39:33 -0500
commit3dc5ea9b31a8c83cffa338aba91adbc9bd387002 (patch)
tree5a9d9682d77fb3a1cfd3dc27654301f69ababf12 /drivers/ieee1394/ieee1394_core.c
parent91efa462054d44ae52b0c6c8325ed5e899f2cd17 (diff)
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 <stefanr@s5r6.in-berlin.de> Acked-by: Pieter Palmers <pieterp@joow.be> Acked-by: Dan Dennedy <dan@dennedy.org>
Diffstat (limited to 'drivers/ieee1394/ieee1394_core.c')
-rw-r--r--drivers/ieee1394/ieee1394_core.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index 1521e57e124b..d791d08c743c 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -33,7 +33,10 @@
33#include <linux/skbuff.h> 33#include <linux/skbuff.h>
34#include <linux/suspend.h> 34#include <linux/suspend.h>
35#include <linux/kthread.h> 35#include <linux/kthread.h>
36#include <linux/preempt.h>
37#include <linux/time.h>
36 38
39#include <asm/system.h>
37#include <asm/byteorder.h> 40#include <asm/byteorder.h>
38 41
39#include "ieee1394_types.h" 42#include "ieee1394_types.h"
@@ -186,6 +189,45 @@ int hpsb_reset_bus(struct hpsb_host *host, int type)
186 } 189 }
187} 190}
188 191
192/**
193 * hpsb_read_cycle_timer - read cycle timer register and system time
194 * @host: host whose isochronous cycle timer register is read
195 * @cycle_timer: address of bitfield to return the register contents
196 * @local_time: address to return the system time
197 *
198 * The format of * @cycle_timer, is described in OHCI 1.1 clause 5.13. This
199 * format is also read from non-OHCI controllers. * @local_time contains the
200 * system time in microseconds since the Epoch, read at the moment when the
201 * cycle timer was read.
202 *
203 * Return value: 0 for success or error number otherwise.
204 */
205int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
206 u64 *local_time)
207{
208 int ctr;
209 struct timeval tv;
210 unsigned long flags;
211
212 if (!host || !cycle_timer || !local_time)
213 return -EINVAL;
214
215 preempt_disable();
216 local_irq_save(flags);
217
218 ctr = host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
219 if (ctr)
220 do_gettimeofday(&tv);
221
222 local_irq_restore(flags);
223 preempt_enable();
224
225 if (!ctr)
226 return -EIO;
227 *cycle_timer = ctr;
228 *local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
229 return 0;
230}
189 231
190int hpsb_bus_reset(struct hpsb_host *host) 232int hpsb_bus_reset(struct hpsb_host *host)
191{ 233{
@@ -1190,6 +1232,7 @@ EXPORT_SYMBOL(hpsb_alloc_packet);
1190EXPORT_SYMBOL(hpsb_free_packet); 1232EXPORT_SYMBOL(hpsb_free_packet);
1191EXPORT_SYMBOL(hpsb_send_packet); 1233EXPORT_SYMBOL(hpsb_send_packet);
1192EXPORT_SYMBOL(hpsb_reset_bus); 1234EXPORT_SYMBOL(hpsb_reset_bus);
1235EXPORT_SYMBOL(hpsb_read_cycle_timer);
1193EXPORT_SYMBOL(hpsb_bus_reset); 1236EXPORT_SYMBOL(hpsb_bus_reset);
1194EXPORT_SYMBOL(hpsb_selfid_received); 1237EXPORT_SYMBOL(hpsb_selfid_received);
1195EXPORT_SYMBOL(hpsb_selfid_complete); 1238EXPORT_SYMBOL(hpsb_selfid_complete);