diff mbox series

[v12,11/17] docs: counter: Document character device interface

Message ID 186e7a1cd7dc822cc9290683b463c3e675959e1a.1625471640.git.vilhelm.gray@gmail.com (mailing list archive)
State New, archived
Headers show
Series Introduce the Counter character device interface | expand

Commit Message

William Breathitt Gray July 5, 2021, 8:18 a.m. UTC
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  | 185 ++++++++++++++----
 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 2 files changed, 145 insertions(+), 41 deletions(-)

Comments

David Lechner July 10, 2021, 8:15 p.m. UTC | #1
On 7/5/21 3:18 AM, William Breathitt Gray 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  | 185 ++++++++++++++----
>   .../userspace-api/ioctl/ioctl-number.rst      |   1 +
>   2 files changed, 145 insertions(+), 41 deletions(-)
> 
> diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
> index f6397218aa4c..62a702e7f994 100644
> --- a/Documentation/driver-api/generic-counter.rst
> +++ b/Documentation/driver-api/generic-counter.rst


> +
> +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::

Won't the :: here make this appear as text instead of an HTML table?

(might need to change ~~~ to --- [top line] and === [middle line])

> +
> +        +~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~+
> +        | 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.

I wouldn't mind seeing more of this documentation in the actual header
file and just referenced here with :c:macro:`COUNTER_ADD_WATCH_IOCTL`

> +
> +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.

To make sure I am understanding this correctly, scope + parent
determines this part of the path:

	/sys/.../counterX/<scope><parent>/<component>

Or in the case that scope == COUNTER_SCOPE_DEVICE then parent
is not applicable:

	/sys/.../counterX/<component>

I suggested parent_id instead of parent earlier, but maybe
scope_id would be a better name? (Or rename scope to parent_type?)

> +
> +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.
William Breathitt Gray July 11, 2021, 10:41 a.m. UTC | #2
On Sat, Jul 10, 2021 at 03:15:06PM -0500, David Lechner wrote:
> On 7/5/21 3:18 AM, William Breathitt Gray 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  | 185 ++++++++++++++----
> >   .../userspace-api/ioctl/ioctl-number.rst      |   1 +
> >   2 files changed, 145 insertions(+), 41 deletions(-)
> > 
> > diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
> > index f6397218aa4c..62a702e7f994 100644
> > --- a/Documentation/driver-api/generic-counter.rst
> > +++ b/Documentation/driver-api/generic-counter.rst
> 
> 
> > +
> > +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::
> 
> Won't the :: here make this appear as text instead of an HTML table?
> 
> (might need to change ~~~ to --- [top line] and === [middle line])

Ack, I'll change this to an HTML table.

> > +
> > +        +~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~+
> > +        | 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.
> 
> I wouldn't mind seeing more of this documentation in the actual header
> file and just referenced here with :c:macro:`COUNTER_ADD_WATCH_IOCTL`

Ack.

> > +
> > +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.
> 
> To make sure I am understanding this correctly, scope + parent
> determines this part of the path:
> 
> 	/sys/.../counterX/<scope><parent>/<component>
> 
> Or in the case that scope == COUNTER_SCOPE_DEVICE then parent
> is not applicable:
> 
> 	/sys/.../counterX/<component>

Yes, that understanding is correct.

> I suggested parent_id instead of parent earlier, but maybe
> scope_id would be a better name? (Or rename scope to parent_type?)

I can see the benefit of more specific naming, but perhaps the current
names are clear enough when they appear in the context of user code. It
becomes rather obvious in a snippet of code that `component.scope`
refers to the scope type of a component while `component.parent` refers
to the specific parent of the component; I don't think the more verbose
`scope_type`/`parent_type` or `scope_id`/`parent_id` namings really add
much benefit here.

I'm not entirely opposed to renaming this, so if other maintainers also
feel this is better renamed then I'll change it. If we do change the
naming, then remaing `scope` to `scope_type` and `parent` to `parent_id`
might be the way to go; "scope_id" seems strange to me because I
envision `scope` as a type rather than an identifiable component.

William Breathitt Gray
diff mbox series

Patch

diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
index f6397218aa4c..62a702e7f994 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,112 @@  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.
+
+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.
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 9bfc2b510c64..cad12ae3f945 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