요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0+
.. |__u16| replace:: :c:type:`__u16 <__u16>`
.. |sdtx_event| replace:: :c:type:`struct sdtx_event <sdtx_event>`
.. |sdtx_event_code| replace:: :c:type:`enum sdtx_event_code <sdtx_event_code>`
.. |sdtx_base_info| replace:: :c:type:`struct sdtx_base_info <sdtx_base_info>`
.. |sdtx_device_mode| replace:: :c:type:`struct sdtx_device_mode <sdtx_device_mode>`
======================================================
User-Space DTX (Clipboard Detachment System) Interface
======================================================
The ``surface_dtx`` driver is responsible for proper clipboard detachment
and re-attachment handling. To this end, it provides the ``/dev/surface/dtx``
device file, through which it can interface with a user-space daemon. This
daemon is then ultimately responsible for determining and taking necessary
actions, such as unmounting devices attached to the base,
unloading/reloading the graphics-driver, user-notifications, etc.
There are two basic communication principles used in this driver: Commands
(in other parts of the documentation also referred to as requests) and
events. Commands are sent to the EC and may have a different implications in
different contexts. Events are sent by the EC upon some internal state
change. Commands are always driver-initiated, whereas events are always
initiated by the EC.
.. contents::
Nomenclature
============
* **Clipboard:**
The detachable upper part of the Surface Book, housing the screen and CPU.
* **Base:**
The lower part of the Surface Book from which the clipboard can be
detached, optionally (model dependent) housing the discrete GPU (dGPU).
* **Latch:**
The mechanism keeping the clipboard attached to the base in normal
operation and allowing it to be detached when requested.
* **Silently ignored commands:**
The command is accepted by the EC as a valid command and acknowledged
(following the standard communication protocol), but the EC does not act
upon it, i.e. ignores it.e upper part of the
Detachment Process
==================
Warning: This part of the documentation is based on reverse engineering and
testing and thus may contain errors or be incomplete.
Latch States
------------
The latch mechanism has two major states: *open* and *closed*. In the
*closed* state (default), the clipboard is secured to the base, whereas in
the *open* state, the clipboard can be removed by a user.
The latch can additionally be locked and, correspondingly, unlocked, which
can influence the detachment procedure. Specifically, this locking mechanism
is intended to prevent the dGPU, positioned in the base of the device, from
being hot-unplugged while in use. More details can be found in the
documentation for the detachment procedure below. By default, the latch is
unlocked.
Detachment Procedure
--------------------
Note that the detachment process is governed fully by the EC. The
``surface_dtx`` driver only relays events from the EC to user-space and
commands from user-space to the EC, i.e. it does not influence this process.
The detachment process is started with the user pressing the *detach* button
on the base of the device or executing the ``SDTX_IOCTL_LATCH_REQUEST`` IOCTL.
Following that:
1. The EC turns on the indicator led on the detach-button, sends a
*detach-request* event (``SDTX_EVENT_REQUEST``), and awaits further
instructions/commands. In case the latch is unlocked, the led will flash
green. If the latch has been locked, the led will be solid red
2. The event is, via the ``surface_dtx`` driver, relayed to user-space, where
an appropriate user-space daemon can handle it and send instructions back
to the EC via IOCTLs provided by this driver.
3. The EC waits for instructions from user-space and acts according to them.
If the EC does not receive any instructions in a given period, it will
time out and continue as follows:
- If the latch is unlocked, the EC will open the latch and the clipboard
can be detached from the base. This is the exact behavior as without
this driver or any user-space daemon. See the ``SDTX_IOCTL_LATCH_CONFIRM``
description below for more details on the follow-up behavior of the EC.
- If the latch is locked, the EC will *not* open the latch, meaning the
clipboard cannot be detached from the base. Furthermore, the EC sends
an cancel event (``SDTX_EVENT_CANCEL``) detailing this with the cancel
reason ``SDTX_DETACH_TIMEDOUT`` (see :ref:`events` for details).
Valid responses by a user-space daemon to a detachment request event are:
- Execute ``SDTX_IOCTL_LATCH_REQUEST``. This will immediately abort the
detachment process. Furthermore, the EC will send a detach-request event,
similar to the user pressing the detach-button to cancel said process (see
below).
- Execute ``SDTX_IOCTL_LATCH_CONFIRM``. This will cause the EC to open the
latch, after which the user can separate clipboard and base.
As this changes the latch state, a *latch-status* event
(``SDTX_EVENT_LATCH_STATUS``) will be sent once the latch has been opened
successfully. If the EC fails to open the latch, e.g. due to hardware
error or low battery, a latch-cancel event (``SDTX_EVENT_CANCEL``) will be
sent with the cancel reason indicating the specific failure.
If the latch is currently locked, the latch will automatically be
unlocked before it is opened.
- Execute ``SDTX_IOCTL_LATCH_HEARTBEAT``. This will reset the internal timeout.
No other actions will be performed, i.e. the detachment process will neither
be completed nor canceled, and the EC will still be waiting for further
responses.
- Execute ``SDTX_IOCTL_LATCH_CANCEL``. This will abort the detachment process,
similar to ``SDTX_IOCTL_LATCH_REQUEST``, described above, or the button
press, described below. A *generic request* event (``SDTX_EVENT_REQUEST``)
is send in response to this. In contrast to those, however, this command
does not trigger a new detachment process if none is currently in
progress.
- Do nothing. The detachment process eventually times out as described in
point 3.
See :ref:`ioctls` for more details on these responses.
It is important to note that, if the user presses the detach button at any
point when a detachment operation is in progress (i.e. after the EC has sent
the initial *detach-request* event (``SDTX_EVENT_REQUEST``) and before it
received the corresponding response concluding the process), the detachment
process is canceled on the EC-level and an identical event is being sent.
Thus a *detach-request* event, by itself, does not signal the start of the
detachment process.
The detachment process may further be canceled by the EC due to hardware
failures or a low clipboard battery. This is done via a cancel event
(``SDTX_EVENT_CANCEL``) with the corresponding cancel reason.
User-Space Interface Documentation
==================================
Error Codes and Status Values
-----------------------------
Error and status codes are divided into different categories, which can be
used to determine if the status code is an error, and, if it is, the
severity and type of that error. The current categories are:
.. flat-table:: Overview of Status/Error Categories.
:widths: 2 1 3
:header-rows: 1
* - Name
- Value
- Short Description
* - ``STATUS``
- ``0x0000``
- Non-error status codes.
* - ``RUNTIME_ERROR``
- ``0x1000``
- Non-critical runtime errors.
* - ``HARDWARE_ERROR``
- ``0x2000``
- Critical hardware failures.
* - ``UNKNOWN``
- ``0xF000``
- Unknown error codes.
Other categories are reserved for future use. The ``SDTX_CATEGORY()`` macro
can be used to determine the category of any status value. The
``SDTX_SUCCESS()`` macro can be used to check if the status value is a
success value (``SDTX_CATEGORY_STATUS``) or if it indicates a failure.
Unknown status or error codes sent by the EC are assigned to the ``UNKNOWN``
category by the driver and may be implemented via their own code in the
future.
Currently used error codes are:
.. flat-table:: Overview of Error Codes.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Category
- Value
- Short Description
* - ``SDTX_DETACH_NOT_FEASIBLE``
- ``RUNTIME``
- ``0x1001``
- Detachment not feasible due to low clipboard battery.
* - ``SDTX_DETACH_TIMEDOUT``
- ``RUNTIME``
- ``0x1002``
- Detachment process timed out while the latch was locked.
* - ``SDTX_ERR_FAILED_TO_OPEN``
- ``HARDWARE``
- ``0x2001``
- Failed to open latch.
* - ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``
- ``HARDWARE``
- ``0x2002``
- Failed to keep latch open.
* - ``SDTX_ERR_FAILED_TO_CLOSE``
- ``HARDWARE``
- ``0x2003``
- Failed to close latch.
Other error codes are reserved for future use. Non-error status codes may
overlap and are generally only unique within their use-case:
.. flat-table:: Latch Status Codes.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Category
- Value
- Short Description
* - ``SDTX_LATCH_CLOSED``
- ``STATUS``
- ``0x0000``
- Latch is closed/has been closed.
* - ``SDTX_LATCH_OPENED``
- ``STATUS``
- ``0x0001``
- Latch is open/has been opened.
.. flat-table:: Base State Codes.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Category
- Value
- Short Description
* - ``SDTX_BASE_DETACHED``
- ``STATUS``
- ``0x0000``
- Base has been detached/is not present.
* - ``SDTX_BASE_ATTACHED``
- ``STATUS``
- ``0x0001``
- Base has been attached/is present.
Again, other codes are reserved for future use.
.. _events:
Events
------
Events can be received by reading from the device file. They are disabled by
default and have to be enabled by executing ``SDTX_IOCTL_EVENTS_ENABLE``
first. All events follow the layout prescribed by |sdtx_event|. Specific
event types can be identified by their event code, described in
|sdtx_event_code|. Note that other event codes are reserved for future use,
thus an event parser must be able to handle any unknown/unsupported event
types gracefully, by relying on the payload length given in the event header.
Currently provided event types are:
.. flat-table:: Overview of DTX events.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Code
- Payload
- Short Description
* - ``SDTX_EVENT_REQUEST``
- ``1``
- ``0`` bytes
- Detachment process initiated/aborted.
* - ``SDTX_EVENT_CANCEL``
- ``2``
- ``2`` bytes
- EC canceled detachment process.
* - ``SDTX_EVENT_BASE_CONNECTION``
- ``3``
- ``4`` bytes
- Base connection state changed.
* - ``SDTX_EVENT_LATCH_STATUS``
- ``4``
- ``2`` bytes
- Latch status changed.
* - ``SDTX_EVENT_DEVICE_MODE``
- ``5``
- ``2`` bytes
- Device mode changed.
Individual events in more detail:
``SDTX_EVENT_REQUEST``
^^^^^^^^^^^^^^^^^^^^^^
Sent when a detachment process is started or, if in progress, aborted by the
user, either via a detach button press or a detach request
(``SDTX_IOCTL_LATCH_REQUEST``) being sent from user-space.
Does not have any payload.
``SDTX_EVENT_CANCEL``
^^^^^^^^^^^^^^^^^^^^^
Sent when a detachment process is canceled by the EC due to unfulfilled
preconditions (e.g. clipboard battery too low to detach) or hardware
failure. The reason for cancellation is given in the event payload detailed
below and can be one of
* ``SDTX_DETACH_TIMEDOUT``: Detachment timed out while the latch was locked.
The latch has neither been opened nor unlocked.
* ``SDTX_DETACH_NOT_FEASIBLE``: Detachment not feasible due to low clipboard
battery.
* ``SDTX_ERR_FAILED_TO_OPEN``: Could not open the latch (hardware failure).
* ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``: Could not keep the latch open (hardware
failure).
* ``SDTX_ERR_FAILED_TO_CLOSE``: Could not close the latch (hardware failure).
Other error codes in this context are reserved for future use.
These codes can be classified via the ``SDTX_CATEGORY()`` macro to discern
between critical hardware errors (``SDTX_CATEGORY_HARDWARE_ERROR``) or
runtime errors (``SDTX_CATEGORY_RUNTIME_ERROR``), the latter of which may
happen during normal operation if certain preconditions for detachment are
not given.
.. flat-table:: Detachment Cancel Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``reason``
- |__u16|
- Reason for cancellation.
``SDTX_EVENT_BASE_CONNECTION``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sent when the base connection state has changed, i.e. when the base has been
attached, detached, or detachment has become infeasible due to low clipboard
battery. The new state and, if a base is connected, ID of the base is
provided as payload of type |sdtx_base_info| with its layout presented
below:
.. flat-table:: Base-Connection-Change Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``state``
- |__u16|
- Base connection state.
* - ``base_id``
- |__u16|
- Type of base connected (zero if none).
Possible values for ``state`` are:
* ``SDTX_BASE_DETACHED``,
* ``SDTX_BASE_ATTACHED``, and
* ``SDTX_DETACH_NOT_FEASIBLE``.
Other values are reserved for future use.
``SDTX_EVENT_LATCH_STATUS``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sent when the latch status has changed, i.e. when the latch has been opened,
closed, or an error occurred. The current status is provided as payload:
.. flat-table:: Latch-Status-Change Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``status``
- |__u16|
- Latch status.
Possible values for ``status`` are:
* ``SDTX_LATCH_CLOSED``,
* ``SDTX_LATCH_OPENED``,
* ``SDTX_ERR_FAILED_TO_OPEN``,
* ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``, and
* ``SDTX_ERR_FAILED_TO_CLOSE``.
Other values are reserved for future use.
``SDTX_EVENT_DEVICE_MODE``
^^^^^^^^^^^^^^^^^^^^^^^^^^
Sent when the device mode has changed. The new device mode is provided as
payload:
.. flat-table:: Device-Mode-Change Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``mode``
- |__u16|
- Device operation mode.
Possible values for ``mode`` are:
* ``SDTX_DEVICE_MODE_TABLET``,
* ``SDTX_DEVICE_MODE_LAPTOP``, and
* ``SDTX_DEVICE_MODE_STUDIO``.
Other values are reserved for future use.
.. _ioctls:
IOCTLs
------
The following IOCTLs are provided:
.. flat-table:: Overview of DTX IOCTLs
:widths: 1 1 1 1 4
:header-rows: 1
* - Type
- Number
- Direction
- Name
- Description
* - ``0xA5``
- ``0x21``
- ``-``
- ``EVENTS_ENABLE``
- Enable events for the current file descriptor.
* - ``0xA5``
- ``0x22``
- ``-``
- ``EVENTS_DISABLE``
- Disable events for the current file descriptor.
* - ``0xA5``
- ``0x23``
- ``-``
- ``LATCH_LOCK``
- Lock the latch.
* - ``0xA5``
- ``0x24``
- ``-``
- ``LATCH_UNLOCK``
- Unlock the latch.
* - ``0xA5``
- ``0x25``
- ``-``
- ``LATCH_REQUEST``
- Request clipboard detachment.
* - ``0xA5``
- ``0x26``
- ``-``
- ``LATCH_CONFIRM``
- Confirm clipboard detachment request.
* - ``0xA5``
- ``0x27``
- ``-``
- ``LATCH_HEARTBEAT``
- Send heartbeat signal to EC.
* - ``0xA5``
- ``0x28``
- ``-``
- ``LATCH_CANCEL``
- Cancel detachment process.
* - ``0xA5``
- ``0x29``
- ``R``
- ``GET_BASE_INFO``
- Get current base/connection information.
* - ``0xA5``
- ``0x2A``
- ``R``
- ``GET_DEVICE_MODE``
- Get current device operation mode.
* - ``0xA5``
- ``0x2B``
- ``R``
- ``GET_LATCH_STATUS``
- Get current device latch status.
``SDTX_IOCTL_EVENTS_ENABLE``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x22)``.
Enable events for the current file descriptor. Events can be obtained by
reading from the device, if enabled. Events are disabled by default.
``SDTX_IOCTL_EVENTS_DISABLE``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x22)``.
Disable events for the current file descriptor. Events can be obtained by
reading from the device, if enabled. Events are disabled by default.
``SDTX_IOCTL_LATCH_LOCK``
^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x23)``.
Locks the latch, causing the detachment procedure to abort without opening
the latch on timeout. The latch is unlocked by default. This command will be
silently ignored if the latch is already locked.
``SDTX_IOCTL_LATCH_UNLOCK``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x24)``.
Unlocks the latch, causing the detachment procedure to open the latch on
timeout. The latch is unlocked by default. This command will not open the
latch when sent during an ongoing detachment process. It will be silently
ignored if the latch is already unlocked.
``SDTX_IOCTL_LATCH_REQUEST``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x25)``.
Generic latch request. Behavior depends on the context: If no
detachment-process is active, detachment is requested. Otherwise the
currently active detachment-process will be aborted.
If a detachment process is canceled by this operation, a generic detachment
request event (``SDTX_EVENT_REQUEST``) will be sent.
This essentially behaves the same as a detachment button press.
``SDTX_IOCTL_LATCH_CONFIRM``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x26)``.
Acknowledges and confirms a latch request. If sent during an ongoing
detachment process, this command causes the latch to be opened immediately.
The latch will also be opened if it has been locked. In this case, the latch
lock is reset to the unlocked state.
This command will be silently ignored if there is currently no detachment
procedure in progress.
``SDTX_IOCTL_LATCH_HEARTBEAT``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x27)``.
Sends a heartbeat, essentially resetting the detachment timeout. This
command can be used to keep the detachment process alive while work required
for the detachment to succeed is still in progress.
This command will be silently ignored if there is currently no detachment
procedure in progress.
``SDTX_IOCTL_LATCH_CANCEL``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x28)``.
Cancels detachment in progress (if any). If a detachment process is canceled
by this operation, a generic detachment request event
(``SDTX_EVENT_REQUEST``) will be sent.
This command will be silently ignored if there is currently no detachment
procedure in progress.
``SDTX_IOCTL_GET_BASE_INFO``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IOR(0xA5, 0x29, struct sdtx_base_info)``.
Get the current base connection state (i.e. attached/detached) and the type
of the base connected to the clipboard. This is command essentially provides
a way to query the information provided by the base connection change event
(``SDTX_EVENT_BASE_CONNECTION``).
Possible values for ``struct sdtx_base_info.state`` are:
* ``SDTX_BASE_DETACHED``,
* ``SDTX_BASE_ATTACHED``, and
* ``SDTX_DETACH_NOT_FEASIBLE``.
Other values are reserved for future use.
``SDTX_IOCTL_GET_DEVICE_MODE``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IOR(0xA5, 0x2A, __u16)``.
Returns the device operation mode, indicating if and how the base is
attached to the clipboard. This is command essentially provides a way to
query the information provided by the device mode change event
(``SDTX_EVENT_DEVICE_MODE``).
Returned values are:
* ``SDTX_DEVICE_MODE_LAPTOP``
* ``SDTX_DEVICE_MODE_TABLET``
* ``SDTX_DEVICE_MODE_STUDIO``
See |sdtx_device_mode| for details. Other values are reserved for future
use.
``SDTX_IOCTL_GET_LATCH_STATUS``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IOR(0xA5, 0x2B, __u16)``.
Get the current latch status or (presumably) the last error encountered when
trying to open/close the latch. This is command essentially provides a way
to query the information provided by the latch status change event
(``SDTX_EVENT_LATCH_STATUS``).
Returned values are:
* ``SDTX_LATCH_CLOSED``,
* ``SDTX_LATCH_OPENED``,
* ``SDTX_ERR_FAILED_TO_OPEN``,
* ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``, and
* ``SDTX_ERR_FAILED_TO_CLOSE``.
Other values are reserved for future use.
A Note on Base IDs
------------------
Base types/IDs provided via ``SDTX_EVENT_BASE_CONNECTION`` or
``SDTX_IOCTL_GET_BASE_INFO`` are directly forwarded from the EC in the lower
byte of the combined |__u16| value, with the driver storing the EC type from
which this ID comes in the high byte (without this, base IDs over different
types of ECs may be overlapping).
The ``SDTX_DEVICE_TYPE()`` macro can be used to determine the EC device
type. This can be one of
* ``SDTX_DEVICE_TYPE_HID``, for Surface Aggregator Module over HID, and
* ``SDTX_DEVICE_TYPE_SSH``, for Surface Aggregator Module over Surface Serial
Hub.
Note that currently only the ``SSH`` type EC is supported, however ``HID``
type is reserved for future use.
Structures and Enums
--------------------
.. kernel-doc:: include/uapi/linux/surface_aggregator/dtx.h
API Users
=========
A user-space daemon utilizing this API can be found at
https://github.com/linux-surface/surface-dtx-daemon.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
User-space DTX interface와 용어
1-48`surface_dtx` driver는 Surface Book clipboard의 올바른 detach와 re-attach 처리를 담당합니다. `/dev/surface/dtx` device file을 통해 user-space daemon과 통신합니다.
User-space daemon은 base에 연결된 device unmount, graphics driver unload·reload, user notification처럼 실제 분리에 필요한 작업을 결정하고 수행할 최종 책임을 집니다.
통신 원리는 command와 event 두 가지입니다. 문서의 다른 부분에서 request라고도 부르는 command는 driver가 시작하여 EC로 보내고, context에 따라 의미가 달라질 수 있습니다. Event는 내부 state 변화가 있을 때 EC가 시작하여 보냅니다.
Clipboard는 screen과 CPU가 들어 있는 Surface Book의 분리 가능한 상부입니다. Base는 clipboard가 분리되는 하부이며 model에 따라 discrete GPU(dGPU)가 들어 있습니다.
Latch는 정상 동작 중 clipboard를 base에 고정하고 요청 시 분리할 수 있게 하는 mechanism입니다.
Silently ignored command는 EC가 유효한 command로 받아 standard protocol에 따라 acknowledge하지만 실제 action은 하지 않는 command입니다.
.. SPDX-License-Identifier: GPL-2.0+
.. |__u16| replace:: :c:type:`__u16 <__u16>`
.. |sdtx_event| replace:: :c:type:`struct sdtx_event <sdtx_event>`
.. |sdtx_event_code| replace:: :c:type:`enum sdtx_event_code <sdtx_event_code>`
.. |sdtx_base_info| replace:: :c:type:`struct sdtx_base_info <sdtx_base_info>`
.. |sdtx_device_mode| replace:: :c:type:`struct sdtx_device_mode <sdtx_device_mode>`
======================================================
User-Space DTX (Clipboard Detachment System) Interface
======================================================
The ``surface_dtx`` driver is responsible for proper clipboard detachment
and re-attachment handling. To this end, it provides the ``/dev/surface/dtx``
device file, through which it can interface with a user-space daemon. This
daemon is then ultimately responsible for determining and taking necessary
actions, such as unmounting devices attached to the base,
unloading/reloading the graphics-driver, user-notifications, etc.
There are two basic communication principles used in this driver: Commands
(in other parts of the documentation also referred to as requests) and
events. Commands are sent to the EC and may have a different implications in
different contexts. Events are sent by the EC upon some internal state
change. Commands are always driver-initiated, whereas events are always
initiated by the EC.
.. contents::
Nomenclature
============
* **Clipboard:**
The detachable upper part of the Surface Book, housing the screen and CPU.
* **Base:**
The lower part of the Surface Book from which the clipboard can be
detached, optionally (model dependent) housing the discrete GPU (dGPU).
* **Latch:**
The mechanism keeping the clipboard attached to the base in normal
operation and allowing it to be detached when requested.
* **Silently ignored commands:**
The command is accepted by the EC as a valid command and acknowledged
(following the standard communication protocol), but the EC does not act
upon it, i.e. ignores it.e upper part of the
분리 절차 경고와 latch state
49-68이 분리 절차 설명은 reverse engineering과 testing을 바탕으로 하므로 오류가 있거나 불완전할 수 있습니다.
Latch mechanism의 주요 state는 `open`과 `closed`입니다. 기본값인 closed에서는 clipboard가 base에 고정되고, open에서는 사용자가 clipboard를 제거할 수 있습니다.
Latch는 별도로 lock 또는 unlock할 수 있으며 이 상태가 detach 절차에 영향을 줍니다. Lock은 base의 dGPU가 사용 중 hot-unplug되는 것을 막기 위한 것입니다. 기본 상태는 unlocked입니다.
Detachment Process
==================
Warning: This part of the documentation is based on reverse engineering and
testing and thus may contain errors or be incomplete.
Latch States
------------
The latch mechanism has two major states: *open* and *closed*. In the
*closed* state (default), the clipboard is secured to the base, whereas in
the *open* state, the clipboard can be removed by a user.
The latch can additionally be locked and, correspondingly, unlocked, which
can influence the detachment procedure. Specifically, this locking mechanism
is intended to prevent the dGPU, positioned in the base of the device, from
being hot-unplugged while in use. More details can be found in the
documentation for the detachment procedure below. By default, the latch is
unlocked.
분리 시작과 timeout
69-102Detach process는 EC가 전적으로 지배합니다. `surface_dtx` driver는 EC event를 user-space로, user-space command를 EC로 전달할 뿐 process 자체에는 영향을 주지 않습니다.
사용자가 base의 detach button을 누르거나 `SDTX_IOCTL_LATCH_REQUEST`를 실행하면 process가 시작됩니다.
EC는 detach button의 indicator LED를 켜고 `SDTX_EVENT_REQUEST` detach-request event를 보낸 뒤 instruction을 기다립니다. Latch가 unlocked이면 LED가 녹색으로 깜박이고 locked이면 빨간색으로 계속 켜집니다.
Driver가 event를 user-space로 전달하면 daemon은 이를 처리하고 IOCTL로 EC에 instruction을 보냅니다.
정해진 시간 동안 instruction이 없으면 timeout됩니다. Latch가 unlocked이면 EC가 latch를 열어 driver나 daemon이 없는 기본 동작과 동일하게 clipboard를 분리할 수 있습니다.
Latch가 locked이면 EC는 latch를 열지 않고 `SDTX_DETACH_TIMEDOUT` reason을 담은 `SDTX_EVENT_CANCEL`을 보냅니다.
EC가 process를 소유하고 latch lock state에 따라 timeout 결과를 결정합니다.
Detachment Procedure
--------------------
Note that the detachment process is governed fully by the EC. The
``surface_dtx`` driver only relays events from the EC to user-space and
commands from user-space to the EC, i.e. it does not influence this process.
The detachment process is started with the user pressing the *detach* button
on the base of the device or executing the ``SDTX_IOCTL_LATCH_REQUEST`` IOCTL.
Following that:
1. The EC turns on the indicator led on the detach-button, sends a
*detach-request* event (``SDTX_EVENT_REQUEST``), and awaits further
instructions/commands. In case the latch is unlocked, the led will flash
green. If the latch has been locked, the led will be solid red
2. The event is, via the ``surface_dtx`` driver, relayed to user-space, where
an appropriate user-space daemon can handle it and send instructions back
to the EC via IOCTLs provided by this driver.
3. The EC waits for instructions from user-space and acts according to them.
If the EC does not receive any instructions in a given period, it will
time out and continue as follows:
- If the latch is unlocked, the EC will open the latch and the clipboard
can be detached from the base. This is the exact behavior as without
this driver or any user-space daemon. See the ``SDTX_IOCTL_LATCH_CONFIRM``
description below for more details on the follow-up behavior of the EC.
- If the latch is locked, the EC will *not* open the latch, meaning the
clipboard cannot be detached from the base. Furthermore, the EC sends
an cancel event (``SDTX_EVENT_CANCEL``) detailing this with the cancel
reason ``SDTX_DETACH_TIMEDOUT`` (see :ref:`events` for details).
User-space response와 cancel 조건
103-150Detach request event에 대한 유효한 user-space response는 request, confirm, heartbeat, cancel, 또는 아무 작업도 하지 않는 것입니다.
`SDTX_IOCTL_LATCH_REQUEST`를 다시 실행하면 현재 detach process를 즉시 abort하고 detach button으로 취소한 때와 비슷한 request event를 보냅니다.
`SDTX_IOCTL_LATCH_CONFIRM`은 latch를 열어 clipboard와 base를 분리할 수 있게 합니다. 성공적으로 열리면 `SDTX_EVENT_LATCH_STATUS`가 발생하고 hardware error나 낮은 battery로 실패하면 구체적 reason을 담은 `SDTX_EVENT_CANCEL`이 발생합니다. 현재 locked라면 먼저 자동 unlock합니다.
`SDTX_IOCTL_LATCH_HEARTBEAT`은 internal timeout만 reset합니다. Process를 완료하거나 취소하지 않고 EC는 계속 response를 기다립니다.
`SDTX_IOCTL_LATCH_CANCEL`은 진행 중 process를 abort하고 `SDTX_EVENT_REQUEST`를 보냅니다. 그러나 진행 중 process가 없다면 새 detach process를 시작하지 않는다는 점이 `LATCH_REQUEST`와 다릅니다.
아무 작업도 하지 않으면 앞서 설명한 timeout 경로로 진행합니다.
Process 진행 중 detach button을 누르면 EC 수준에서 취소되고 시작 때와 동일한 request event가 전송됩니다. 따라서 `SDTX_EVENT_REQUEST` 하나만으로 process 시작 여부를 판단할 수 없습니다.
EC는 hardware failure나 낮은 clipboard battery 때문에 process를 취소할 수도 있으며 이때 대응 reason을 담은 `SDTX_EVENT_CANCEL`을 보냅니다.
Valid responses by a user-space daemon to a detachment request event are:
- Execute ``SDTX_IOCTL_LATCH_REQUEST``. This will immediately abort the
detachment process. Furthermore, the EC will send a detach-request event,
similar to the user pressing the detach-button to cancel said process (see
below).
- Execute ``SDTX_IOCTL_LATCH_CONFIRM``. This will cause the EC to open the
latch, after which the user can separate clipboard and base.
As this changes the latch state, a *latch-status* event
(``SDTX_EVENT_LATCH_STATUS``) will be sent once the latch has been opened
successfully. If the EC fails to open the latch, e.g. due to hardware
error or low battery, a latch-cancel event (``SDTX_EVENT_CANCEL``) will be
sent with the cancel reason indicating the specific failure.
If the latch is currently locked, the latch will automatically be
unlocked before it is opened.
- Execute ``SDTX_IOCTL_LATCH_HEARTBEAT``. This will reset the internal timeout.
No other actions will be performed, i.e. the detachment process will neither
be completed nor canceled, and the EC will still be waiting for further
responses.
- Execute ``SDTX_IOCTL_LATCH_CANCEL``. This will abort the detachment process,
similar to ``SDTX_IOCTL_LATCH_REQUEST``, described above, or the button
press, described below. A *generic request* event (``SDTX_EVENT_REQUEST``)
is send in response to this. In contrast to those, however, this command
does not trigger a new detachment process if none is currently in
progress.
- Do nothing. The detachment process eventually times out as described in
point 3.
See :ref:`ioctls` for more details on these responses.
It is important to note that, if the user presses the detach button at any
point when a detachment operation is in progress (i.e. after the EC has sent
the initial *detach-request* event (``SDTX_EVENT_REQUEST``) and before it
received the corresponding response concluding the process), the detachment
process is canceled on the EC-level and an identical event is being sent.
Thus a *detach-request* event, by itself, does not signal the start of the
detachment process.
The detachment process may further be canceled by the EC due to hardware
failures or a low clipboard battery. This is done via a cancel event
(``SDTX_EVENT_CANCEL``) with the corresponding cancel reason.
Status와 error category
151-194Error와 status code는 category로 나뉘며, 이를 통해 error 여부와 error의 severity·type을 판단할 수 있습니다.
`SDTX_CATEGORY()` macro는 임의 status value의 category를 판별합니다. `SDTX_SUCCESS()`는 value가 성공 category인 `SDTX_CATEGORY_STATUS`인지 failure인지 확인합니다.
EC가 보내는 알려지지 않은 status 또는 error code는 driver가 `UNKNOWN` category에 배정합니다. 이후 자체 code로 구현될 수 있습니다. 다른 category도 미래 사용을 위해 예약되어 있습니다.
User-Space Interface Documentation
==================================
Error Codes and Status Values
-----------------------------
Error and status codes are divided into different categories, which can be
used to determine if the status code is an error, and, if it is, the
severity and type of that error. The current categories are:
.. flat-table:: Overview of Status/Error Categories.
:widths: 2 1 3
:header-rows: 1
* - Name
- Value
- Short Description
* - ``STATUS``
- ``0x0000``
- Non-error status codes.
* - ``RUNTIME_ERROR``
- ``0x1000``
- Non-critical runtime errors.
* - ``HARDWARE_ERROR``
- ``0x2000``
- Critical hardware failures.
* - ``UNKNOWN``
- ``0xF000``
- Unknown error codes.
Other categories are reserved for future use. The ``SDTX_CATEGORY()`` macro
can be used to determine the category of any status value. The
``SDTX_SUCCESS()`` macro can be used to check if the status value is a
success value (``SDTX_CATEGORY_STATUS``) or if it indicates a failure.
Unknown status or error codes sent by the EC are assigned to the ``UNKNOWN``
category by the driver and may be implemented via their own code in the
future.
Error, latch, base status code
195-273현재 error code는 detach feasibility·timeout과 latch open·유지·close hardware failure를 구분합니다. 나머지는 미래 사용을 위해 예약되어 있습니다.
Non-error status code는 서로 겹칠 수 있으며 일반적으로 각 use case 안에서만 unique합니다.
Currently used error codes are:
.. flat-table:: Overview of Error Codes.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Category
- Value
- Short Description
* - ``SDTX_DETACH_NOT_FEASIBLE``
- ``RUNTIME``
- ``0x1001``
- Detachment not feasible due to low clipboard battery.
* - ``SDTX_DETACH_TIMEDOUT``
- ``RUNTIME``
- ``0x1002``
- Detachment process timed out while the latch was locked.
* - ``SDTX_ERR_FAILED_TO_OPEN``
- ``HARDWARE``
- ``0x2001``
- Failed to open latch.
* - ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``
- ``HARDWARE``
- ``0x2002``
- Failed to keep latch open.
* - ``SDTX_ERR_FAILED_TO_CLOSE``
- ``HARDWARE``
- ``0x2003``
- Failed to close latch.
Other error codes are reserved for future use. Non-error status codes may
overlap and are generally only unique within their use-case:
.. flat-table:: Latch Status Codes.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Category
- Value
- Short Description
* - ``SDTX_LATCH_CLOSED``
- ``STATUS``
- ``0x0000``
- Latch is closed/has been closed.
* - ``SDTX_LATCH_OPENED``
- ``STATUS``
- ``0x0001``
- Latch is open/has been opened.
.. flat-table:: Base State Codes.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Category
- Value
- Short Description
* - ``SDTX_BASE_DETACHED``
- ``STATUS``
- ``0x0000``
- Base has been detached/is not present.
* - ``SDTX_BASE_ATTACHED``
- ``STATUS``
- ``0x0001``
- Base has been attached/is present.
Again, other codes are reserved for future use.
DTX event 형식과 종류
274-323Event는 device file에서 읽습니다. 기본적으로 disable되어 있으므로 먼저 `SDTX_IOCTL_EVENTS_ENABLE`을 실행해야 합니다.
모든 event는 `struct sdtx_event` layout을 따르고 `enum sdtx_event_code`로 type을 식별합니다.
다른 event code는 미래 사용을 위해 예약되어 있으므로 parser는 event header의 payload length를 사용하여 unknown 또는 unsupported type을 안전하게 건너뛰어야 합니다.
.. _events:
Events
------
Events can be received by reading from the device file. They are disabled by
default and have to be enabled by executing ``SDTX_IOCTL_EVENTS_ENABLE``
first. All events follow the layout prescribed by |sdtx_event|. Specific
event types can be identified by their event code, described in
|sdtx_event_code|. Note that other event codes are reserved for future use,
thus an event parser must be able to handle any unknown/unsupported event
types gracefully, by relying on the payload length given in the event header.
Currently provided event types are:
.. flat-table:: Overview of DTX events.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Code
- Payload
- Short Description
* - ``SDTX_EVENT_REQUEST``
- ``1``
- ``0`` bytes
- Detachment process initiated/aborted.
* - ``SDTX_EVENT_CANCEL``
- ``2``
- ``2`` bytes
- EC canceled detachment process.
* - ``SDTX_EVENT_BASE_CONNECTION``
- ``3``
- ``4`` bytes
- Base connection state changed.
* - ``SDTX_EVENT_LATCH_STATUS``
- ``4``
- ``2`` bytes
- Latch status changed.
* - ``SDTX_EVENT_DEVICE_MODE``
- ``5``
- ``2`` bytes
- Device mode changed.
Individual events in more detail:
Request와 Cancel event
324-374`SDTX_EVENT_REQUEST`는 detach button 또는 user-space의 `SDTX_IOCTL_LATCH_REQUEST` 때문에 process가 시작되거나 진행 중 process가 사용자에 의해 abort될 때 전송됩니다. Payload는 없습니다.
`SDTX_EVENT_CANCEL`은 낮은 clipboard battery 같은 precondition 미충족이나 hardware failure 때문에 EC가 process를 취소할 때 전송됩니다. Payload의 `__u16 reason`이 원인을 나타냅니다.
Reason은 locked timeout인 `SDTX_DETACH_TIMEDOUT`, 낮은 battery인 `SDTX_DETACH_NOT_FEASIBLE`, latch open·open 유지·close 실패인 세 hardware error 중 하나일 수 있습니다.
`SDTX_CATEGORY()`로 critical hardware error와 normal operation 중 precondition 때문에 발생할 수 있는 runtime error를 구분합니다. 다른 error code는 미래 사용을 위해 예약되어 있습니다.
``SDTX_EVENT_REQUEST``
^^^^^^^^^^^^^^^^^^^^^^
Sent when a detachment process is started or, if in progress, aborted by the
user, either via a detach button press or a detach request
(``SDTX_IOCTL_LATCH_REQUEST``) being sent from user-space.
Does not have any payload.
``SDTX_EVENT_CANCEL``
^^^^^^^^^^^^^^^^^^^^^
Sent when a detachment process is canceled by the EC due to unfulfilled
preconditions (e.g. clipboard battery too low to detach) or hardware
failure. The reason for cancellation is given in the event payload detailed
below and can be one of
* ``SDTX_DETACH_TIMEDOUT``: Detachment timed out while the latch was locked.
The latch has neither been opened nor unlocked.
* ``SDTX_DETACH_NOT_FEASIBLE``: Detachment not feasible due to low clipboard
battery.
* ``SDTX_ERR_FAILED_TO_OPEN``: Could not open the latch (hardware failure).
* ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``: Could not keep the latch open (hardware
failure).
* ``SDTX_ERR_FAILED_TO_CLOSE``: Could not close the latch (hardware failure).
Other error codes in this context are reserved for future use.
These codes can be classified via the ``SDTX_CATEGORY()`` macro to discern
between critical hardware errors (``SDTX_CATEGORY_HARDWARE_ERROR``) or
runtime errors (``SDTX_CATEGORY_RUNTIME_ERROR``), the latter of which may
happen during normal operation if certain preconditions for detachment are
not given.
.. flat-table:: Detachment Cancel Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``reason``
- |__u16|
- Reason for cancellation.
Base connection event
375-407`SDTX_EVENT_BASE_CONNECTION`은 base가 attach·detach되거나 낮은 clipboard battery 때문에 detach가 불가능해지는 등 base connection state가 바뀔 때 전송됩니다.
Payload는 `struct sdtx_base_info`이며 `__u16 state`와 `__u16 base_id`를 담습니다. Base가 없으면 `base_id`는 0입니다.
`state`는 `SDTX_BASE_DETACHED`, `SDTX_BASE_ATTACHED`, `SDTX_DETACH_NOT_FEASIBLE` 중 하나이며 다른 값은 미래 사용을 위해 예약되어 있습니다.
``SDTX_EVENT_BASE_CONNECTION``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sent when the base connection state has changed, i.e. when the base has been
attached, detached, or detachment has become infeasible due to low clipboard
battery. The new state and, if a base is connected, ID of the base is
provided as payload of type |sdtx_base_info| with its layout presented
below:
.. flat-table:: Base-Connection-Change Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``state``
- |__u16|
- Base connection state.
* - ``base_id``
- |__u16|
- Type of base connected (zero if none).
Possible values for ``state`` are:
* ``SDTX_BASE_DETACHED``,
* ``SDTX_BASE_ATTACHED``, and
* ``SDTX_DETACH_NOT_FEASIBLE``.
Other values are reserved for future use.
Latch status와 device mode event
408-460`SDTX_EVENT_LATCH_STATUS`는 latch가 open·close되거나 error가 발생하여 status가 바뀔 때 전송됩니다. Payload의 `__u16 status`는 closed, opened, open 실패, open 유지 실패, close 실패 중 하나입니다.
`SDTX_EVENT_DEVICE_MODE`는 device mode가 바뀔 때 전송됩니다. Payload의 `__u16 mode`는 `SDTX_DEVICE_MODE_TABLET`, `SDTX_DEVICE_MODE_LAPTOP`, `SDTX_DEVICE_MODE_STUDIO` 중 하나입니다.
두 event 모두 나머지 value는 미래 사용을 위해 예약되어 있습니다.
``SDTX_EVENT_LATCH_STATUS``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sent when the latch status has changed, i.e. when the latch has been opened,
closed, or an error occurred. The current status is provided as payload:
.. flat-table:: Latch-Status-Change Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``status``
- |__u16|
- Latch status.
Possible values for ``status`` are:
* ``SDTX_LATCH_CLOSED``,
* ``SDTX_LATCH_OPENED``,
* ``SDTX_ERR_FAILED_TO_OPEN``,
* ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``, and
* ``SDTX_ERR_FAILED_TO_CLOSE``.
Other values are reserved for future use.
``SDTX_EVENT_DEVICE_MODE``
^^^^^^^^^^^^^^^^^^^^^^^^^^
Sent when the device mode has changed. The new device mode is provided as
payload:
.. flat-table:: Device-Mode-Change Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``mode``
- |__u16|
- Device operation mode.
Possible values for ``mode`` are:
* ``SDTX_DEVICE_MODE_TABLET``,
* ``SDTX_DEVICE_MODE_LAPTOP``, and
* ``SDTX_DEVICE_MODE_STUDIO``.
Other values are reserved for future use.
DTX IOCTL 목록
461-544DTX user-space interface는 type `0xA5` 아래 event control, latch command, state query를 위한 열한 IOCTL을 제공합니다.
.. _ioctls:
IOCTLs
------
The following IOCTLs are provided:
.. flat-table:: Overview of DTX IOCTLs
:widths: 1 1 1 1 4
:header-rows: 1
* - Type
- Number
- Direction
- Name
- Description
* - ``0xA5``
- ``0x21``
- ``-``
- ``EVENTS_ENABLE``
- Enable events for the current file descriptor.
* - ``0xA5``
- ``0x22``
- ``-``
- ``EVENTS_DISABLE``
- Disable events for the current file descriptor.
* - ``0xA5``
- ``0x23``
- ``-``
- ``LATCH_LOCK``
- Lock the latch.
* - ``0xA5``
- ``0x24``
- ``-``
- ``LATCH_UNLOCK``
- Unlock the latch.
* - ``0xA5``
- ``0x25``
- ``-``
- ``LATCH_REQUEST``
- Request clipboard detachment.
* - ``0xA5``
- ``0x26``
- ``-``
- ``LATCH_CONFIRM``
- Confirm clipboard detachment request.
* - ``0xA5``
- ``0x27``
- ``-``
- ``LATCH_HEARTBEAT``
- Send heartbeat signal to EC.
* - ``0xA5``
- ``0x28``
- ``-``
- ``LATCH_CANCEL``
- Cancel detachment process.
* - ``0xA5``
- ``0x29``
- ``R``
- ``GET_BASE_INFO``
- Get current base/connection information.
* - ``0xA5``
- ``0x2A``
- ``R``
- ``GET_DEVICE_MODE``
- Get current device operation mode.
* - ``0xA5``
- ``0x2B``
- ``R``
- ``GET_LATCH_STATUS``
- Get current device latch status.
Event와 latch lock IOCTL
545-579`SDTX_IOCTL_EVENTS_ENABLE`은 원문에 `_IO(0xA5, 0x22)`로 정의되어 있으며 현재 file descriptor의 event를 enable합니다. Event는 기본 disable이고 enable 뒤 device read로 얻습니다.
`SDTX_IOCTL_EVENTS_DISABLE`도 `_IO(0xA5, 0x22)`로 정의되어 있으며 현재 file descriptor의 event를 disable합니다.
`SDTX_IOCTL_LATCH_LOCK`은 `_IO(0xA5, 0x23)`입니다. Latch를 lock하여 timeout 때 latch를 열지 않고 detach 절차를 abort하게 합니다. 이미 locked이면 silently ignored됩니다.
`SDTX_IOCTL_LATCH_UNLOCK`은 `_IO(0xA5, 0x24)`입니다. Timeout 때 latch를 열도록 unlock하지만 진행 중 detach process에서 보낸다고 즉시 latch를 열지는 않습니다. 이미 unlocked이면 silently ignored됩니다.
EVENTS_ENABLE의 number 표기는 원문 정의를 그대로 보존했습니다.
``SDTX_IOCTL_EVENTS_ENABLE``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x22)``.
Enable events for the current file descriptor. Events can be obtained by
reading from the device, if enabled. Events are disabled by default.
``SDTX_IOCTL_EVENTS_DISABLE``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x22)``.
Disable events for the current file descriptor. Events can be obtained by
reading from the device, if enabled. Events are disabled by default.
``SDTX_IOCTL_LATCH_LOCK``
^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x23)``.
Locks the latch, causing the detachment procedure to abort without opening
the latch on timeout. The latch is unlocked by default. This command will be
silently ignored if the latch is already locked.
``SDTX_IOCTL_LATCH_UNLOCK``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x24)``.
Unlocks the latch, causing the detachment procedure to open the latch on
timeout. The latch is unlocked by default. This command will not open the
latch when sent during an ongoing detachment process. It will be silently
ignored if the latch is already unlocked.
Detach control IOCTL
580-630`SDTX_IOCTL_LATCH_REQUEST`는 `_IO(0xA5, 0x25)`인 generic request입니다. 진행 중 process가 없으면 detach를 요청하고, 있으면 현재 process를 abort하여 `SDTX_EVENT_REQUEST`를 보냅니다. Detach button과 본질적으로 같은 동작입니다.
`SDTX_IOCTL_LATCH_CONFIRM`은 `_IO(0xA5, 0x26)`입니다. 진행 중 request를 acknowledge·confirm하고 latch를 즉시 엽니다. Locked 상태라면 lock을 unlocked로 reset한 뒤 엽니다. 진행 중 process가 없으면 silently ignored됩니다.
`SDTX_IOCTL_LATCH_HEARTBEAT`은 `_IO(0xA5, 0x27)`이며 detach timeout을 reset하여 필요한 준비 작업 동안 process를 유지합니다. 진행 중 process가 없으면 silently ignored됩니다.
`SDTX_IOCTL_LATCH_CANCEL`은 `_IO(0xA5, 0x28)`이며 진행 중 process가 있으면 취소하고 `SDTX_EVENT_REQUEST`를 보냅니다. 진행 중 process가 없으면 silently ignored됩니다.
진행 중 process 유무에 따라 request와 cancel의 의미가 달라집니다.
``SDTX_IOCTL_LATCH_REQUEST``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x25)``.
Generic latch request. Behavior depends on the context: If no
detachment-process is active, detachment is requested. Otherwise the
currently active detachment-process will be aborted.
If a detachment process is canceled by this operation, a generic detachment
request event (``SDTX_EVENT_REQUEST``) will be sent.
This essentially behaves the same as a detachment button press.
``SDTX_IOCTL_LATCH_CONFIRM``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x26)``.
Acknowledges and confirms a latch request. If sent during an ongoing
detachment process, this command causes the latch to be opened immediately.
The latch will also be opened if it has been locked. In this case, the latch
lock is reset to the unlocked state.
This command will be silently ignored if there is currently no detachment
procedure in progress.
``SDTX_IOCTL_LATCH_HEARTBEAT``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x27)``.
Sends a heartbeat, essentially resetting the detachment timeout. This
command can be used to keep the detachment process alive while work required
for the detachment to succeed is still in progress.
This command will be silently ignored if there is currently no detachment
procedure in progress.
``SDTX_IOCTL_LATCH_CANCEL``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x28)``.
Cancels detachment in progress (if any). If a detachment process is canceled
by this operation, a generic detachment request event
(``SDTX_EVENT_REQUEST``) will be sent.
This command will be silently ignored if there is currently no detachment
procedure in progress.
Base, mode, latch query IOCTL
631-688`SDTX_IOCTL_GET_BASE_INFO`는 `_IOR(0xA5, 0x29, struct sdtx_base_info)`이며 현재 base attach state와 clipboard에 연결된 base type을 반환합니다. `SDTX_EVENT_BASE_CONNECTION`이 제공하는 정보를 query하는 경로입니다.
반환 `state`는 `SDTX_BASE_DETACHED`, `SDTX_BASE_ATTACHED`, `SDTX_DETACH_NOT_FEASIBLE` 중 하나입니다.
`SDTX_IOCTL_GET_DEVICE_MODE`는 `_IOR(0xA5, 0x2A, __u16)`이며 base가 clipboard에 연결된 방식인 operation mode를 반환합니다. `SDTX_EVENT_DEVICE_MODE` 정보의 query 경로이며 LAPTOP, TABLET, STUDIO 값을 반환합니다.
`SDTX_IOCTL_GET_LATCH_STATUS`는 `_IOR(0xA5, 0x2B, __u16)`이며 현재 latch status 또는 open·close 시 마지막으로 발생한 것으로 추정되는 error를 반환합니다. `SDTX_EVENT_LATCH_STATUS` 정보의 query 경로입니다.
``SDTX_IOCTL_GET_BASE_INFO``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IOR(0xA5, 0x29, struct sdtx_base_info)``.
Get the current base connection state (i.e. attached/detached) and the type
of the base connected to the clipboard. This is command essentially provides
a way to query the information provided by the base connection change event
(``SDTX_EVENT_BASE_CONNECTION``).
Possible values for ``struct sdtx_base_info.state`` are:
* ``SDTX_BASE_DETACHED``,
* ``SDTX_BASE_ATTACHED``, and
* ``SDTX_DETACH_NOT_FEASIBLE``.
Other values are reserved for future use.
``SDTX_IOCTL_GET_DEVICE_MODE``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IOR(0xA5, 0x2A, __u16)``.
Returns the device operation mode, indicating if and how the base is
attached to the clipboard. This is command essentially provides a way to
query the information provided by the device mode change event
(``SDTX_EVENT_DEVICE_MODE``).
Returned values are:
* ``SDTX_DEVICE_MODE_LAPTOP``
* ``SDTX_DEVICE_MODE_TABLET``
* ``SDTX_DEVICE_MODE_STUDIO``
See |sdtx_device_mode| for details. Other values are reserved for future
use.
``SDTX_IOCTL_GET_LATCH_STATUS``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IOR(0xA5, 0x2B, __u16)``.
Get the current latch status or (presumably) the last error encountered when
trying to open/close the latch. This is command essentially provides a way
to query the information provided by the latch status change event
(``SDTX_EVENT_LATCH_STATUS``).
Returned values are:
* ``SDTX_LATCH_CLOSED``,
* ``SDTX_LATCH_OPENED``,
* ``SDTX_ERR_FAILED_TO_OPEN``,
* ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``, and
* ``SDTX_ERR_FAILED_TO_CLOSE``.
Other values are reserved for future use.
Base ID encoding과 UAPI type
689-713`SDTX_EVENT_BASE_CONNECTION` 또는 `SDTX_IOCTL_GET_BASE_INFO`가 제공하는 base type/ID는 결합된 `__u16`의 low byte에 EC 값을 그대로 전달합니다.
High byte에는 그 ID를 제공한 EC type을 driver가 저장합니다. 이를 생략하면 서로 다른 EC type의 base ID가 겹칠 수 있습니다.
`SDTX_DEVICE_TYPE()` macro로 EC device type을 판별합니다. `SDTX_DEVICE_TYPE_HID`는 HID 기반 Surface Aggregator Module, `SDTX_DEVICE_TYPE_SSH`는 Surface Serial Hub 기반 module입니다.
현재는 SSH type EC만 지원하며 HID type은 미래 사용을 위해 예약되어 있습니다.
Structure와 enum 정의는 `include/uapi/linux/surface_aggregator/dtx.h`의 kernel-doc에서 가져옵니다.
A Note on Base IDs
------------------
Base types/IDs provided via ``SDTX_EVENT_BASE_CONNECTION`` or
``SDTX_IOCTL_GET_BASE_INFO`` are directly forwarded from the EC in the lower
byte of the combined |__u16| value, with the driver storing the EC type from
which this ID comes in the high byte (without this, base IDs over different
types of ECs may be overlapping).
The ``SDTX_DEVICE_TYPE()`` macro can be used to determine the EC device
type. This can be one of
* ``SDTX_DEVICE_TYPE_HID``, for Surface Aggregator Module over HID, and
* ``SDTX_DEVICE_TYPE_SSH``, for Surface Aggregator Module over Surface Serial
Hub.
Note that currently only the ``SSH`` type EC is supported, however ``HID``
type is reserved for future use.
Structures and Enums
--------------------
.. kernel-doc:: include/uapi/linux/surface_aggregator/dtx.h
DTX API user-space daemon
714-718이 API를 사용하는 user-space daemon은 `linux-surface/surface-dtx-daemon` repository에서 찾을 수 있습니다.
API Users
=========
A user-space daemon utilizing this API can be found at
https://github.com/linux-surface/surface-dtx-daemon.
요약과 해설
dtx.rst:1-718`surface_dtx`는 EC가 소유한 Surface Book detach process를 user-space daemon에 중계합니다. Latch lock state는 timeout 때 open 여부를 결정하고 daemon은 request·confirm·heartbeat·cancel로 응답합니다. ABI는 category화된 status/error, 다섯 event payload, event·latch·state query IOCTL을 제공하며 base ID는 high byte EC type과 low byte EC ID로 구성됩니다.