lkml.org 
[lkml]   [2007]   [Feb]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH update] ieee1394: cycle timer read extension for raw1394/libraw1394
    From: Pieter Palmers <pieterp@joow.be>

    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 <stefanr@s5r6.in-berlin.de>
    ---

    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 majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-02-03 14:01    [W:3.166 / U:0.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site