diff options
Diffstat (limited to 'Documentation/driver-api/surface_aggregator/clients/cdev.rst')
-rw-r--r-- | Documentation/driver-api/surface_aggregator/clients/cdev.rst | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/Documentation/driver-api/surface_aggregator/clients/cdev.rst b/Documentation/driver-api/surface_aggregator/clients/cdev.rst new file mode 100644 index 000000000..0134a841a --- /dev/null +++ b/Documentation/driver-api/surface_aggregator/clients/cdev.rst @@ -0,0 +1,204 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +.. |ssam_cdev_request| replace:: :c:type:`struct ssam_cdev_request <ssam_cdev_request>` +.. |ssam_cdev_request_flags| replace:: :c:type:`enum ssam_cdev_request_flags <ssam_cdev_request_flags>` +.. |ssam_cdev_event| replace:: :c:type:`struct ssam_cdev_event <ssam_cdev_event>` + +============================== +User-Space EC Interface (cdev) +============================== + +The ``surface_aggregator_cdev`` module provides a misc-device for the SSAM +controller to allow for a (more or less) direct connection from user-space to +the SAM EC. It is intended to be used for development and debugging, and +therefore should not be used or relied upon in any other way. Note that this +module is not loaded automatically, but instead must be loaded manually. + +The provided interface is accessible through the ``/dev/surface/aggregator`` +device-file. All functionality of this interface is provided via IOCTLs. +These IOCTLs and their respective input/output parameter structs are defined in +``include/uapi/linux/surface_aggregator/cdev.h``. + +A small python library and scripts for accessing this interface can be found +at https://github.com/linux-surface/surface-aggregator-module/tree/master/scripts/ssam. + +.. contents:: + + +Receiving Events +================ + +Events can be received by reading from the device-file. The are represented by +the |ssam_cdev_event| datatype. + +Before events are available to be read, however, the desired notifiers must be +registered via the ``SSAM_CDEV_NOTIF_REGISTER`` IOCTL. Notifiers are, in +essence, callbacks, called when the EC sends an event. They are, in this +interface, associated with a specific target category and device-file-instance. +They forward any event of this category to the buffer of the corresponding +instance, from which it can then be read. + +Notifiers themselves do not enable events on the EC. Thus, it may additionally +be necessary to enable events via the ``SSAM_CDEV_EVENT_ENABLE`` IOCTL. While +notifiers work per-client (i.e. per-device-file-instance), events are enabled +globally, for the EC and all of its clients (regardless of userspace or +non-userspace). The ``SSAM_CDEV_EVENT_ENABLE`` and ``SSAM_CDEV_EVENT_DISABLE`` +IOCTLs take care of reference counting the events, such that an event is +enabled as long as there is a client that has requested it. + +Note that enabled events are not automatically disabled once the client +instance is closed. Therefore any client process (or group of processes) should +balance their event enable calls with the corresponding event disable calls. It +is, however, perfectly valid to enable and disable events on different client +instances. For example, it is valid to set up notifiers and read events on +client instance ``A``, enable those events on instance ``B`` (note that these +will also be received by A since events are enabled/disabled globally), and +after no more events are desired, disable the previously enabled events via +instance ``C``. + + +Controller IOCTLs +================= + +The following IOCTLs are provided: + +.. flat-table:: Controller IOCTLs + :widths: 1 1 1 1 4 + :header-rows: 1 + + * - Type + - Number + - Direction + - Name + - Description + + * - ``0xA5`` + - ``1`` + - ``WR`` + - ``REQUEST`` + - Perform synchronous SAM request. + + * - ``0xA5`` + - ``2`` + - ``W`` + - ``NOTIF_REGISTER`` + - Register event notifier. + + * - ``0xA5`` + - ``3`` + - ``W`` + - ``NOTIF_UNREGISTER`` + - Unregister event notifier. + + * - ``0xA5`` + - ``4`` + - ``W`` + - ``EVENT_ENABLE`` + - Enable event source. + + * - ``0xA5`` + - ``5`` + - ``W`` + - ``EVENT_DISABLE`` + - Disable event source. + + +``SSAM_CDEV_REQUEST`` +--------------------- + +Defined as ``_IOWR(0xA5, 1, struct ssam_cdev_request)``. + +Executes a synchronous SAM request. The request specification is passed in +as argument of type |ssam_cdev_request|, which is then written to/modified +by the IOCTL to return status and result of the request. + +Request payload data must be allocated separately and is passed in via the +``payload.data`` and ``payload.length`` members. If a response is required, +the response buffer must be allocated by the caller and passed in via the +``response.data`` member. The ``response.length`` member must be set to the +capacity of this buffer, or if no response is required, zero. Upon +completion of the request, the call will write the response to the response +buffer (if its capacity allows it) and overwrite the length field with the +actual size of the response, in bytes. + +Additionally, if the request has a response, this must be indicated via the +request flags, as is done with in-kernel requests. Request flags can be set +via the ``flags`` member and the values correspond to the values found in +|ssam_cdev_request_flags|. + +Finally, the status of the request itself is returned in the ``status`` +member (a negative errno value indicating failure). Note that failure +indication of the IOCTL is separated from failure indication of the request: +The IOCTL returns a negative status code if anything failed during setup of +the request (``-EFAULT``) or if the provided argument or any of its fields +are invalid (``-EINVAL``). In this case, the status value of the request +argument may be set, providing more detail on what went wrong (e.g. +``-ENOMEM`` for out-of-memory), but this value may also be zero. The IOCTL +will return with a zero status code in case the request has been set up, +submitted, and completed (i.e. handed back to user-space) successfully from +inside the IOCTL, but the request ``status`` member may still be negative in +case the actual execution of the request failed after it has been submitted. + +A full definition of the argument struct is provided below. + +``SSAM_CDEV_NOTIF_REGISTER`` +---------------------------- + +Defined as ``_IOW(0xA5, 2, struct ssam_cdev_notifier_desc)``. + +Register a notifier for the event target category specified in the given +notifier description with the specified priority. Notifiers registration is +required to receive events, but does not enable events themselves. After a +notifier for a specific target category has been registered, all events of that +category will be forwarded to the userspace client and can then be read from +the device file instance. Note that events may have to be enabled, e.g. via the +``SSAM_CDEV_EVENT_ENABLE`` IOCTL, before the EC will send them. + +Only one notifier can be registered per target category and client instance. If +a notifier has already been registered, this IOCTL will fail with ``-EEXIST``. + +Notifiers will automatically be removed when the device file instance is +closed. + +``SSAM_CDEV_NOTIF_UNREGISTER`` +------------------------------ + +Defined as ``_IOW(0xA5, 3, struct ssam_cdev_notifier_desc)``. + +Unregisters the notifier associated with the specified target category. The +priority field will be ignored by this IOCTL. If no notifier has been +registered for this client instance and the given category, this IOCTL will +fail with ``-ENOENT``. + +``SSAM_CDEV_EVENT_ENABLE`` +-------------------------- + +Defined as ``_IOW(0xA5, 4, struct ssam_cdev_event_desc)``. + +Enable the event associated with the given event descriptor. + +Note that this call will not register a notifier itself, it will only enable +events on the controller. If you want to receive events by reading from the +device file, you will need to register the corresponding notifier(s) on that +instance. + +Events are not automatically disabled when the device file is closed. This must +be done manually, via a call to the ``SSAM_CDEV_EVENT_DISABLE`` IOCTL. + +``SSAM_CDEV_EVENT_DISABLE`` +--------------------------- + +Defined as ``_IOW(0xA5, 5, struct ssam_cdev_event_desc)``. + +Disable the event associated with the given event descriptor. + +Note that this will not unregister any notifiers. Events may still be received +and forwarded to user-space after this call. The only safe way of stopping +events from being received is unregistering all previously registered +notifiers. + + +Structures and Enums +==================== + +.. kernel-doc:: include/uapi/linux/surface_aggregator/cdev.h |