lkml.org 
[lkml]   [2021]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v8 18/22] docs: counter: Document character device interface
    On Fri, 12 Feb 2021 21:13:42 +0900
    William Breathitt Gray <vilhelm.gray@gmail.com> wrote:

    > This patch adds high-level documentation about the Counter subsystem
    > character device interface.
    >
    > Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
    > ---
    > Documentation/driver-api/generic-counter.rst | 243 +++++++++++++++---
    > .../userspace-api/ioctl/ioctl-number.rst | 1 +
    > 2 files changed, 203 insertions(+), 41 deletions(-)
    >
    > diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
    > index f6397218aa4c..3be109dc81bb 100644
    > --- a/Documentation/driver-api/generic-counter.rst
    > +++ b/Documentation/driver-api/generic-counter.rst
    > @@ -223,19 +223,6 @@ whether an input line is differential or single-ended) and instead focus
    > on the core idea of what the data and process represent (e.g. position
    > as interpreted from quadrature encoding data).
    >
    > -Userspace Interface
    > -===================
    > -
    > -Several sysfs attributes are generated by the Generic Counter interface,
    > -and reside under the /sys/bus/counter/devices/counterX directory, where
    > -counterX refers to the respective counter device. Please see
    > -Documentation/ABI/testing/sysfs-bus-counter for detailed
    > -information on each Generic Counter interface sysfs attribute.
    > -
    > -Through these sysfs attributes, programs and scripts may interact with
    > -the Generic Counter paradigm Counts, Signals, and Synapses of respective
    > -counter devices.
    > -
    > Driver API
    > ==========
    >
    > @@ -388,16 +375,16 @@ userspace interface components::
    > / driver callbacks /
    > -------------------
    > |
    > - +---------------+
    > - |
    > - V
    > - +--------------------+
    > - | Counter sysfs |
    > - +--------------------+
    > - | Translates to the |
    > - | standard Counter |
    > - | sysfs output |
    > - +--------------------+
    > + +---------------+---------------+
    > + | |
    > + V V
    > + +--------------------+ +---------------------+
    > + | Counter sysfs | | Counter chrdev |
    > + +--------------------+ +---------------------+
    > + | Translates to the | | Translates to the |
    > + | standard Counter | | standard Counter |
    > + | sysfs output | | character device |
    > + +--------------------+ +---------------------+
    >
    > Thereafter, data can be transferred directly between the Counter device
    > driver and Counter userspace interface::
    > @@ -428,23 +415,30 @@ driver and Counter userspace interface::
    > / u64 /
    > ----------
    > |
    > - +---------------+
    > - |
    > - V
    > - +--------------------+
    > - | Counter sysfs |
    > - +--------------------+
    > - | Translates to the |
    > - | standard Counter |
    > - | sysfs output |
    > - |--------------------|
    > - | Type: const char * |
    > - | Value: "42" |
    > - +--------------------+
    > - |
    > - ---------------
    > - / const char * /
    > - ---------------
    > + +---------------+---------------+
    > + | |
    > + V V
    > + +--------------------+ +---------------------+
    > + | Counter sysfs | | Counter chrdev |
    > + +--------------------+ +---------------------+
    > + | Translates to the | | Translates to the |
    > + | standard Counter | | standard Counter |
    > + | sysfs output | | character device |
    > + |--------------------| |---------------------|
    > + | Type: const char * | | Type: u64 |
    > + | Value: "42" | | Value: 42 |
    > + +--------------------+ +---------------------+
    > + | |
    > + --------------- -----------------------
    > + / const char * / / struct counter_event /
    > + --------------- -----------------------
    > + | |
    > + | V
    > + | +-----------+
    > + | | read |
    > + | +-----------+
    > + | \ Count: 42 /
    > + | -----------
    > |
    > V
    > +--------------------------------------------------+
    > @@ -453,7 +447,7 @@ driver and Counter userspace interface::
    > \ Count: "42" /
    > --------------------------------------------------
    >
    > -There are three primary components involved:
    > +There are four primary components involved:
    >
    > Counter device driver
    > ---------------------
    > @@ -473,3 +467,170 @@ and vice versa.
    > Please refer to the ``Documentation/ABI/testing/sysfs-bus-counter`` file
    > for a detailed breakdown of the available Generic Counter interface
    > sysfs attributes.
    > +
    > +Counter chrdev
    > +--------------
    > +Translates counter data to the standard Counter character device; data
    > +is transferred via standard character device read calls, while Counter
    > +events are configured via ioctl calls.
    > +
    > +Sysfs Interface
    > +===============
    > +
    > +Several sysfs attributes are generated by the Generic Counter interface,
    > +and reside under the ``/sys/bus/counter/devices/counterX`` directory,
    > +where ``X`` is to the respective counter device id. Please see
    > +``Documentation/ABI/testing/sysfs-bus-counter`` for detailed information
    > +on each Generic Counter interface sysfs attribute.
    > +
    > +Through these sysfs attributes, programs and scripts may interact with
    > +the Generic Counter paradigm Counts, Signals, and Synapses of respective
    > +counter devices.
    > +
    > +Counter Character Device
    > +========================
    > +
    > +Counter character device nodes are created under the ``/dev`` directory
    > +as ``counterX``, where ``X`` is the respective counter device id.
    > +Defines for the standard Counter data types are exposed via the
    > +userspace ``include/uapi/linux/counter.h`` file.
    > +
    > +Counter events
    > +--------------
    > +Counter device drivers can support Counter events by utilizing the
    > +``counter_push_event`` function::
    > +
    > + void counter_push_event(struct counter_device *const counter, const u8 event,
    > + const u8 channel);
    > +
    > +The event id is specified by the ``event`` parameter; the event channel
    > +id is specified by the ``channel`` parameter. When this function is
    > +called, the Counter data associated with the respective event is
    > +gathered, and a ``struct counter_event`` is generated for each datum and
    > +pushed to userspace.
    > +
    > +Counter events can be configured by users to report various Counter
    > +data of interest. This can be conceptualized as a list of Counter
    > +component read calls to perform. For example::
    > +
    > + +~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~+
    > + | COUNTER_EVENT_OVERFLOW | COUNTER_EVENT_INDEX |
    > + +~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~+
    > + | Channel 0 | Channel 0 |
    > + +------------------------+------------------------+
    > + | * Count 0 | * Signal 0 |
    > + | * Count 1 | * Signal 0 Extension 0 |
    > + | * Signal 3 | * Extension 4 |
    > + | * Count 4 Extension 2 +------------------------+
    > + | * Signal 5 Extension 0 | Channel 1 |
    > + | +------------------------+
    > + | | * Signal 4 |
    > + | | * Signal 4 Extension 0 |
    > + | | * Count 7 |
    > + +------------------------+------------------------+
    > +
    > +When ``counter_push_event(counter, COUNTER_EVENT_INDEX, 1)`` is called
    > +for example, it will go down the list for the ``COUNTER_EVENT_INDEX``
    > +event channel 1 and execute the read callbacks for Signal 4, Signal 4
    > +Extension 0, and Count 4 -- the data returned for each is pushed to a
    > +kfifo as a ``struct counter_event``, which userspace can retrieve via a
    > +standard read operation on the respective character device node.
    > +
    > +Userspace
    > +---------
    > +Userspace applications can configure Counter events via ioctl operations
    > +on the Counter character device node. There following ioctl codes are
    > +supported and provided by the ``linux/counter.h`` userspace header file:
    > +
    > +* COUNTER_ADD_WATCH_IOCTL:
    > + Queues a Counter watch for the specified event. The queued watches
    > + will not be applied until ``COUNTER_ENABLE_EVENTS_IOCTL`` is called.
    > +
    > +* COUNTER_ENABLE_EVENTS_IOCTL:
    > + Enables monitoring the events specified by the Counter watches that
    > + were queued by ``COUNTER_ADD_WATCH_IOCTL``. If events are already
    > + enabled, the new set of watches replaces the old one. Calling this
    > + ioctl also has the effect of clearing the queue of watches added by
    > + ``COUNTER_ADD_WATCH_IOCTL``.
    > +
    > +* COUNTER_DISABLE_EVENTS_IOCTL:
    > + Stops monitoring the previously enabled events.

    Is there a way to remove a watch?

    > +
    > +To configure events to gather Counter data, users first populate a
    > +``struct counter_watch`` with the relevant event id, event channel id,
    > +and the information for the desired Counter component from which to
    > +read, and then pass it via the ``COUNTER_ADD_WATCH_IOCTL`` ioctl
    > +command.
    > +
    > +Note that an event can be watched without gathering Counter data by
    > +setting the ``component.type`` member equal to
    > +``COUNTER_COMPONENT_NONE``. With this configuration the Counter
    > +character device will simply populate the event timestamps for those
    > +respective ``struct counter_event`` elements and ignore the component
    > +value.
    > +
    > +The ``COUNTER_ADD_WATCH_IOCTL`` command will buffer these Counter
    > +watches. When ready, the ``COUNTER_ENABLE_EVENTS_IOCTL`` ioctl command
    > +may be used to activate these Counter watches.
    > +
    > +Userspace applications can then execute a ``read`` operation (optionally
    > +calling ``poll`` first) on the Counter character device node to retrieve
    > +``struct counter_event`` elements with the desired data.
    > +
    > +For example, the following userspace code opens ``/dev/counter0``,
    > +configures the ``COUNTER_EVENT_INDEX`` event channel 0 to gather Count 0
    > +and Count 1, and prints out the data as it becomes available on the
    > +character device node::
    > +

    Consider adding an example program under tools/

    > + #include <fcntl.h>
    > + #include <linux/counter.h>
    > + #include <stdio.h>
    > + #include <string.h>
    > + #include <sys/ioctl.h>
    > + #include <unistd.h>
    > +
    > + struct counter_watch watches[2] = {
    > + {
    > + .component.type = COUNTER_COMPONENT_COUNT,
    > + .component.scope = COUNTER_SCOPE_COUNT,
    > + .component.parent = 0,

    Good to add comments on what these elements actually are?

    > + .event = COUNTER_EVENT_INDEX,
    > + .channel = 0,
    > + },
    > + {
    > + .component.type = COUNTER_COMPONENT_COUNT,
    > + .component.scope = COUNTER_SCOPE_COUNT,
    > + .component.parent = 1,
    > + .event = COUNTER_EVENT_INDEX,
    > + .channel = 0,
    > + },
    > + };
    > +
    > + int main(void)
    > + {
    > + int fd;
    > + struct counter_event event_data[2];
    > +
    > + fd = open("/dev/counter0", O_RDWR);
    > +
    > + ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches);
    > + ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + 1);
    > + ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL);
    > +
    > + for (;;) {
    > + read(fd, event_data, sizeof(event_data));
    > +
    > + printf("Timestamp 0: %llu\tCount 0: %llu\n"
    > + "Error Message 0: %s\n"
    > + "Timestamp 1: %llu\tCount 1: %llu\n"
    > + "Error Message 1: %s\n",
    > + (unsigned long long)event_data[0].timestamp,
    > + (unsigned long long)event_data[0].value,
    > + strerror(event_data[0].status),
    > + (unsigned long long)event_data[1].timestamp,
    > + (unsigned long long)event_data[1].value,
    > + strerror(event_data[1].status));
    > + }
    > +
    > + return 0;
    > + }
    > diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
    > index a4c75a28c839..8ddca931ec4e 100644
    > --- a/Documentation/userspace-api/ioctl/ioctl-number.rst
    > +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
    > @@ -88,6 +88,7 @@ Code Seq# Include File Comments
    > <http://infiniband.sourceforge.net/>
    > 0x20 all drivers/cdrom/cm206.h
    > 0x22 all scsi/sg.h
    > +0x3E 00-0F linux/counter.h <mailto:linux-iio@vger.kernel.org>
    > '!' 00-1F uapi/linux/seccomp.h
    > '#' 00-3F IEEE 1394 Subsystem
    > Block for the entire subsystem

    \
     
     \ /
      Last update: 2021-02-14 18:49    [W:4.573 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site