Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0+
0002 
0003 .. |ssam_cdev_request| replace:: :c:type:`struct ssam_cdev_request <ssam_cdev_request>`
0004 .. |ssam_cdev_request_flags| replace:: :c:type:`enum ssam_cdev_request_flags <ssam_cdev_request_flags>`
0005 .. |ssam_cdev_event| replace:: :c:type:`struct ssam_cdev_event <ssam_cdev_event>`
0006 
0007 ==============================
0008 User-Space EC Interface (cdev)
0009 ==============================
0010 
0011 The ``surface_aggregator_cdev`` module provides a misc-device for the SSAM
0012 controller to allow for a (more or less) direct connection from user-space to
0013 the SAM EC. It is intended to be used for development and debugging, and
0014 therefore should not be used or relied upon in any other way. Note that this
0015 module is not loaded automatically, but instead must be loaded manually.
0016 
0017 The provided interface is accessible through the ``/dev/surface/aggregator``
0018 device-file. All functionality of this interface is provided via IOCTLs.
0019 These IOCTLs and their respective input/output parameter structs are defined in
0020 ``include/uapi/linux/surface_aggregator/cdev.h``.
0021 
0022 A small python library and scripts for accessing this interface can be found
0023 at https://github.com/linux-surface/surface-aggregator-module/tree/master/scripts/ssam.
0024 
0025 .. contents::
0026 
0027 
0028 Receiving Events
0029 ================
0030 
0031 Events can be received by reading from the device-file. The are represented by
0032 the |ssam_cdev_event| datatype.
0033 
0034 Before events are available to be read, however, the desired notifiers must be
0035 registered via the ``SSAM_CDEV_NOTIF_REGISTER`` IOCTL. Notifiers are, in
0036 essence, callbacks, called when the EC sends an event. They are, in this
0037 interface, associated with a specific target category and device-file-instance.
0038 They forward any event of this category to the buffer of the corresponding
0039 instance, from which it can then be read.
0040 
0041 Notifiers themselves do not enable events on the EC. Thus, it may additionally
0042 be necessary to enable events via the ``SSAM_CDEV_EVENT_ENABLE`` IOCTL. While
0043 notifiers work per-client (i.e. per-device-file-instance), events are enabled
0044 globally, for the EC and all of its clients (regardless of userspace or
0045 non-userspace). The ``SSAM_CDEV_EVENT_ENABLE`` and ``SSAM_CDEV_EVENT_DISABLE``
0046 IOCTLs take care of reference counting the events, such that an event is
0047 enabled as long as there is a client that has requested it.
0048 
0049 Note that enabled events are not automatically disabled once the client
0050 instance is closed. Therefore any client process (or group of processes) should
0051 balance their event enable calls with the corresponding event disable calls. It
0052 is, however, perfectly valid to enable and disable events on different client
0053 instances. For example, it is valid to set up notifiers and read events on
0054 client instance ``A``, enable those events on instance ``B`` (note that these
0055 will also be received by A since events are enabled/disabled globally), and
0056 after no more events are desired, disable the previously enabled events via
0057 instance ``C``.
0058 
0059 
0060 Controller IOCTLs
0061 =================
0062 
0063 The following IOCTLs are provided:
0064 
0065 .. flat-table:: Controller IOCTLs
0066    :widths: 1 1 1 1 4
0067    :header-rows: 1
0068 
0069    * - Type
0070      - Number
0071      - Direction
0072      - Name
0073      - Description
0074 
0075    * - ``0xA5``
0076      - ``1``
0077      - ``WR``
0078      - ``REQUEST``
0079      - Perform synchronous SAM request.
0080 
0081    * - ``0xA5``
0082      - ``2``
0083      - ``W``
0084      - ``NOTIF_REGISTER``
0085      - Register event notifier.
0086 
0087    * - ``0xA5``
0088      - ``3``
0089      - ``W``
0090      - ``NOTIF_UNREGISTER``
0091      - Unregister event notifier.
0092 
0093    * - ``0xA5``
0094      - ``4``
0095      - ``W``
0096      - ``EVENT_ENABLE``
0097      - Enable event source.
0098 
0099    * - ``0xA5``
0100      - ``5``
0101      - ``W``
0102      - ``EVENT_DISABLE``
0103      - Disable event source.
0104 
0105 
0106 ``SSAM_CDEV_REQUEST``
0107 ---------------------
0108 
0109 Defined as ``_IOWR(0xA5, 1, struct ssam_cdev_request)``.
0110 
0111 Executes a synchronous SAM request. The request specification is passed in
0112 as argument of type |ssam_cdev_request|, which is then written to/modified
0113 by the IOCTL to return status and result of the request.
0114 
0115 Request payload data must be allocated separately and is passed in via the
0116 ``payload.data`` and ``payload.length`` members. If a response is required,
0117 the response buffer must be allocated by the caller and passed in via the
0118 ``response.data`` member. The ``response.length`` member must be set to the
0119 capacity of this buffer, or if no response is required, zero. Upon
0120 completion of the request, the call will write the response to the response
0121 buffer (if its capacity allows it) and overwrite the length field with the
0122 actual size of the response, in bytes.
0123 
0124 Additionally, if the request has a response, this must be indicated via the
0125 request flags, as is done with in-kernel requests. Request flags can be set
0126 via the ``flags`` member and the values correspond to the values found in
0127 |ssam_cdev_request_flags|.
0128 
0129 Finally, the status of the request itself is returned in the ``status``
0130 member (a negative errno value indicating failure). Note that failure
0131 indication of the IOCTL is separated from failure indication of the request:
0132 The IOCTL returns a negative status code if anything failed during setup of
0133 the request (``-EFAULT``) or if the provided argument or any of its fields
0134 are invalid (``-EINVAL``). In this case, the status value of the request
0135 argument may be set, providing more detail on what went wrong (e.g.
0136 ``-ENOMEM`` for out-of-memory), but this value may also be zero. The IOCTL
0137 will return with a zero status code in case the request has been set up,
0138 submitted, and completed (i.e. handed back to user-space) successfully from
0139 inside the IOCTL, but the request ``status`` member may still be negative in
0140 case the actual execution of the request failed after it has been submitted.
0141 
0142 A full definition of the argument struct is provided below.
0143 
0144 ``SSAM_CDEV_NOTIF_REGISTER``
0145 ----------------------------
0146 
0147 Defined as ``_IOW(0xA5, 2, struct ssam_cdev_notifier_desc)``.
0148 
0149 Register a notifier for the event target category specified in the given
0150 notifier description with the specified priority. Notifiers registration is
0151 required to receive events, but does not enable events themselves. After a
0152 notifier for a specific target category has been registered, all events of that
0153 category will be forwarded to the userspace client and can then be read from
0154 the device file instance. Note that events may have to be enabled, e.g. via the
0155 ``SSAM_CDEV_EVENT_ENABLE`` IOCTL, before the EC will send them.
0156 
0157 Only one notifier can be registered per target category and client instance. If
0158 a notifier has already been registered, this IOCTL will fail with ``-EEXIST``.
0159 
0160 Notifiers will automatically be removed when the device file instance is
0161 closed.
0162 
0163 ``SSAM_CDEV_NOTIF_UNREGISTER``
0164 ------------------------------
0165 
0166 Defined as ``_IOW(0xA5, 3, struct ssam_cdev_notifier_desc)``.
0167 
0168 Unregisters the notifier associated with the specified target category. The
0169 priority field will be ignored by this IOCTL. If no notifier has been
0170 registered for this client instance and the given category, this IOCTL will
0171 fail with ``-ENOENT``.
0172 
0173 ``SSAM_CDEV_EVENT_ENABLE``
0174 --------------------------
0175 
0176 Defined as ``_IOW(0xA5, 4, struct ssam_cdev_event_desc)``.
0177 
0178 Enable the event associated with the given event descriptor.
0179 
0180 Note that this call will not register a notifier itself, it will only enable
0181 events on the controller. If you want to receive events by reading from the
0182 device file, you will need to register the corresponding notifier(s) on that
0183 instance.
0184 
0185 Events are not automatically disabled when the device file is closed. This must
0186 be done manually, via a call to the ``SSAM_CDEV_EVENT_DISABLE`` IOCTL.
0187 
0188 ``SSAM_CDEV_EVENT_DISABLE``
0189 ---------------------------
0190 
0191 Defined as ``_IOW(0xA5, 5, struct ssam_cdev_event_desc)``.
0192 
0193 Disable the event associated with the given event descriptor.
0194 
0195 Note that this will not unregister any notifiers. Events may still be received
0196 and forwarded to user-space after this call. The only safe way of stopping
0197 events from being received is unregistering all previously registered
0198 notifiers.
0199 
0200 
0201 Structures and Enums
0202 ====================
0203 
0204 .. kernel-doc:: include/uapi/linux/surface_aggregator/cdev.h