lkml.org 
[lkml]   [2010]   [Feb]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] firewire: cdev: add more flexible cycle timer ioctl
    The system time from CLOCK_REALTIME is not monotonic, hence problematic
    for the main user of the FW_CDEV_IOC_GET_CYCLE_TIMER ioctl. This issue
    exists in its successor ABI, i.e. raw1394, too.
    http://subversion.ffado.org/ticket/242

    We now offer an alternative ioctl which lets the caller choose between
    CLOCK_REALTIME, CLOCK_MONOTONIC, and CLOCK_MONOTONIC_RAW as source of
    the local time, very similar to the clock_gettime libc function. The
    format of the local time return value matches that of clock_gettime
    (seconds and nanoseconds, instead of a single microseconds value from
    the existing ioctl).

    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
    ---
    drivers/firewire/core-cdev.c | 37 ++++++++++++++++++++++++++++------
    include/linux/firewire-cdev.h | 31 +++++++++++++++++++++++++---
    2 files changed, 58 insertions(+), 10 deletions(-)

    Index: b/drivers/firewire/core-cdev.c
    ===================================================================
    --- a/drivers/firewire/core-cdev.c
    +++ b/drivers/firewire/core-cdev.c
    @@ -1030,22 +1030,46 @@ static int ioctl_stop_iso(struct client
    return fw_iso_context_stop(client->iso_context);
    }

    -static int ioctl_get_cycle_timer(struct client *client, void *buffer)
    +static int ioctl_get_cycle_timer2(struct client *client, void *buffer)
    {
    - struct fw_cdev_get_cycle_timer *request = buffer;
    + struct fw_cdev_get_cycle_timer2 *request = buffer;
    struct fw_card *card = client->device->card;
    - struct timeval tv;
    + struct timespec ts = {0, 0};
    u32 cycle_time;
    + int ret = 0;

    local_irq_disable();

    cycle_time = card->driver->get_cycle_time(card);
    - do_gettimeofday(&tv);
    +
    + switch (request->clk_id) {
    + case CLOCK_REALTIME: getnstimeofday(&ts); break;
    + case CLOCK_MONOTONIC: do_posix_clock_monotonic_gettime(&ts); break;
    + case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts); break;
    + default:
    + ret = -EINVAL;
    + }

    local_irq_enable();

    - request->local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
    - request->cycle_timer = cycle_time;
    + request->tv_sec = ts.tv_sec;
    + request->tv_nsec = ts.tv_nsec;
    + request->cycle_timer = cycle_time;
    +
    + return ret;
    +}
    +
    +static int ioctl_get_cycle_timer(struct client *client, void *buffer)
    +{
    + struct fw_cdev_get_cycle_timer *request = buffer;
    + struct fw_cdev_get_cycle_timer2 ct2;
    +
    + ct2.clk_id = CLOCK_REALTIME;
    + ioctl_get_cycle_timer2(client, &ct2);
    +
    + request->local_time = ct2.tv_sec * USEC_PER_SEC +
    + ct2.tv_nsec / NSEC_PER_USEC;
    + request->cycle_timer = ct2.cycle_timer;

    return 0;
    }
    @@ -1319,6 +1343,7 @@ static int (* const ioctl_handlers[])(st
    ioctl_get_speed,
    ioctl_send_broadcast_request,
    ioctl_send_stream_packet,
    + ioctl_get_cycle_timer2,
    };

    static int dispatch_ioctl(struct client *client,
    Index: b/include/linux/firewire-cdev.h
    ===================================================================
    --- a/include/linux/firewire-cdev.h
    +++ b/include/linux/firewire-cdev.h
    @@ -248,6 +248,9 @@ union fw_cdev_event {
    #define FW_CDEV_IOC_SEND_BROADCAST_REQUEST _IOW('#', 0x12, struct fw_cdev_send_request)
    #define FW_CDEV_IOC_SEND_STREAM_PACKET _IOW('#', 0x13, struct fw_cdev_send_stream_packet)

    +/* available since kernel version 2.6.34 */
    +#define FW_CDEV_IOC_GET_CYCLE_TIMER2 _IOWR('#', 0x14, struct fw_cdev_get_cycle_timer2)
    +
    /*
    * FW_CDEV_VERSION History
    * 1 (2.6.22) - initial version
    @@ -544,14 +547,15 @@ struct fw_cdev_stop_iso {
    /**
    * struct fw_cdev_get_cycle_timer - read cycle timer register
    * @local_time: system time, in microseconds since the Epoch
    - * @cycle_timer: isochronous cycle timer, as per OHCI 1.1 clause 5.13
    + * @cycle_timer: Cycle Time register contents
    *
    * The %FW_CDEV_IOC_GET_CYCLE_TIMER ioctl reads the isochronous cycle timer
    - * and also the system clock. This allows to express the receive time of an
    - * isochronous packet as a system time with microsecond accuracy.
    + * and also the system clock (%CLOCK_REALTIME). This allows to express the
    + * receive time of an isochronous packet as a system time.
    *
    * @cycle_timer consists of 7 bits cycleSeconds, 13 bits cycleCount, and
    - * 12 bits cycleOffset, in host byte order.
    + * 12 bits cycleOffset, in host byte order. Cf. the Cycle Time register
    + * per IEEE 1394 or Isochronous Cycle Timer register per OHCI-1394.
    */
    struct fw_cdev_get_cycle_timer {
    __u64 local_time;
    @@ -559,6 +563,25 @@ struct fw_cdev_get_cycle_timer {
    };

    /**
    + * struct fw_cdev_get_cycle_timer2 - read cycle timer register
    + * @tv_sec: system time, seconds
    + * @tv_nsec: system time, sub-seconds part in nanoseconds
    + * @clk_id: input parameter, clock from which to get the system time
    + * @cycle_timer: Cycle Time register contents
    + *
    + * The %FW_CDEV_IOC_GET_CYCLE_TIMER2 works like
    + * %FW_CDEV_IOC_GET_CYCLE_TIMER but lets you choose a clock like with POSIX'
    + * clock_gettime function. Supported @clk_id values are POSIX' %CLOCK_REALTIME
    + * and %CLOCK_MONOTONIC and Linux' %CLOCK_MONOTONIC_RAW.
    + */
    +struct fw_cdev_get_cycle_timer2 {
    + __s64 tv_sec;
    + __s32 tv_nsec;
    + __s32 clk_id;
    + __u32 cycle_timer;
    +};
    +
    +/**
    * struct fw_cdev_allocate_iso_resource - (De)allocate a channel or bandwidth
    * @closure: Passed back to userspace in correponding iso resource events
    * @channels: Isochronous channels of which one is to be (de)allocated
    --
    Stefan Richter
    -=====-==-=- --=- =--==
    http://arcgraph.de/sr/


    \
     
     \ /
      Last update: 2010-02-19 21:07    [W:0.028 / U:59.384 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site