205 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. 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
 |