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