요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
=============================
TTY Driver and TTY Operations
=============================
.. contents:: :local:
Allocation
==========
The first thing a driver needs to do is to allocate a struct tty_driver. This
is done by tty_alloc_driver() (or __tty_alloc_driver()). Next, the newly
allocated structure is filled with information. See `TTY Driver Reference`_ at
the end of this document on what actually shall be filled in.
The allocation routines expect a number of devices the driver can handle at
most and flags. Flags are those starting ``TTY_DRIVER_`` listed and described
in `TTY Driver Flags`_ below.
When the driver is about to be freed, tty_driver_kref_put() is called on that.
It will decrements the reference count and if it reaches zero, the driver is
freed.
For reference, both allocation and deallocation functions are explained here in
detail:
.. kernel-doc:: include/linux/tty_driver.h
:identifiers: tty_alloc_driver
.. kernel-doc:: drivers/tty/tty_io.c
:identifiers: __tty_alloc_driver tty_driver_kref_put
TTY Driver Flags
----------------
Here comes the documentation of flags accepted by tty_alloc_driver() (or
__tty_alloc_driver()):
.. kernel-doc:: include/linux/tty_driver.h
:identifiers: tty_driver_flag
----
Registration
============
When a struct tty_driver is allocated and filled in, it can be registered using
tty_register_driver(). It is recommended to pass ``TTY_DRIVER_DYNAMIC_DEV`` in
flags of tty_alloc_driver(). If it is not passed, *all* devices are also
registered during tty_register_driver() and the following paragraph of
registering devices can be skipped for such drivers. However, the struct
tty_port part in `Registering Devices`_ is still relevant there.
.. kernel-doc:: drivers/tty/tty_io.c
:identifiers: tty_register_driver tty_unregister_driver
Registering Devices
-------------------
Every TTY device shall be backed by a struct tty_port. Usually, TTY drivers
embed tty_port into device's private structures. Further details about handling
tty_port can be found in :doc:`tty_port`. The driver is also recommended to use
tty_port's reference counting by tty_port_get() and tty_port_put(). The final
put is supposed to free the tty_port including the device's private struct.
Unless ``TTY_DRIVER_DYNAMIC_DEV`` was passed as flags to tty_alloc_driver(),
TTY driver is supposed to register every device discovered in the system
(the latter is preferred). This is performed by tty_register_device(). Or by
tty_register_device_attr() if the driver wants to expose some information
through struct attribute_group. Both of them register ``index``'th device and
upon return, the device can be opened. There are also preferred tty_port
variants described in `Linking Devices to Ports`_ later. It is up to driver to
manage free indices and choosing the right one. The TTY layer only refuses to
register more devices than passed to tty_alloc_driver().
When the device is opened, the TTY layer allocates struct tty_struct and starts
calling operations from :c:member:`tty_driver.ops`, see `TTY Operations
Reference`_.
The registration routines are documented as follows:
.. kernel-doc:: drivers/tty/tty_io.c
:identifiers: tty_register_device tty_register_device_attr
tty_unregister_device
----
Linking Devices to Ports
------------------------
As stated earlier, every TTY device shall have a struct tty_port assigned to
it. It must be known to the TTY layer at :c:member:`tty_driver.ops.install()`
at latest. There are few helpers to *link* the two. Ideally, the driver uses
tty_port_register_device() or tty_port_register_device_attr() instead of
tty_register_device() and tty_register_device_attr() at the registration time.
This way, the driver needs not care about linking later on.
If that is not possible, the driver still can link the tty_port to a specific
index *before* the actual registration by tty_port_link_device(). If it still
does not fit, tty_port_install() can be used from the
:c:member:`tty_driver.ops.install` hook as a last resort. The last one is
dedicated mostly for in-memory devices like PTY where tty_ports are allocated
on demand.
The linking routines are documented here:
.. kernel-doc:: drivers/tty/tty_port.c
:identifiers: tty_port_link_device tty_port_register_device
tty_port_register_device_attr
----
TTY Driver Reference
====================
All members of struct tty_driver are documented here. The required members are
noted at the end. struct tty_operations are documented next.
.. kernel-doc:: include/linux/tty_driver.h
:identifiers: tty_driver
----
TTY Operations Reference
========================
When a TTY is registered, these driver hooks can be invoked by the TTY layer:
.. kernel-doc:: include/linux/tty_driver.h
:identifiers: tty_operations
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
TTY driver와 operations
1-8이 문서는 TTY driver의 할당·등록·장치 연결 절차와 TTY operations callback reference를 설명합니다. 아래 절들은 driver 수명주기를 실제 API와 kernel-doc source path에 맞춰 구성합니다.
driver 구조체 할당부터 operations callback 호출까지의 큰 순서입니다.
.. SPDX-License-Identifier: GPL-2.0
=============================
TTY Driver and TTY Operations
=============================
.. contents:: :local:
할당·해제와 driver flags
9-42드라이버가 가장 먼저 해야 할 일은 `struct tty_driver`를 할당하는 것입니다. `tty_alloc_driver()` 또는 `__tty_alloc_driver()`로 할당한 뒤 새 구조체에 정보를 채웁니다. 실제로 채워야 할 항목은 문서 끝의 TTY Driver Reference를 참조합니다.
할당 함수는 드라이버가 처리할 수 있는 최대 device 수와 flags를 받습니다. flags는 `TTY_DRIVER_`로 시작하며 아래 TTY Driver Flags 절에 나열되고 설명됩니다.
driver를 해제할 때는 `tty_driver_kref_put()`을 호출합니다. 이 함수가 reference count를 줄이고 count가 0에 도달하면 driver가 해제됩니다.
`tty_alloc_driver`의 kernel-doc은 `include/linux/tty_driver.h`에서, `__tty_alloc_driver`와 `tty_driver_kref_put`은 `drivers/tty/tty_io.c`에서 가져옵니다. 허용되는 flag 집합 `tty_driver_flag`는 다시 `include/linux/tty_driver.h`에서 문서화합니다.
Allocation
==========
The first thing a driver needs to do is to allocate a struct tty_driver. This
is done by tty_alloc_driver() (or __tty_alloc_driver()). Next, the newly
allocated structure is filled with information. See `TTY Driver Reference`_ at
the end of this document on what actually shall be filled in.
The allocation routines expect a number of devices the driver can handle at
most and flags. Flags are those starting ``TTY_DRIVER_`` listed and described
in `TTY Driver Flags`_ below.
When the driver is about to be freed, tty_driver_kref_put() is called on that.
It will decrements the reference count and if it reaches zero, the driver is
freed.
For reference, both allocation and deallocation functions are explained here in
detail:
.. kernel-doc:: include/linux/tty_driver.h
:identifiers: tty_alloc_driver
.. kernel-doc:: drivers/tty/tty_io.c
:identifiers: __tty_alloc_driver tty_driver_kref_put
TTY Driver Flags
----------------
Here comes the documentation of flags accepted by tty_alloc_driver() (or
__tty_alloc_driver()):
.. kernel-doc:: include/linux/tty_driver.h
:identifiers: tty_driver_flag
----
TTY driver 등록
43-56할당하고 필드를 채운 `struct tty_driver`는 `tty_register_driver()`로 등록합니다. `tty_alloc_driver()` flags에는 `TTY_DRIVER_DYNAMIC_DEV`를 전달하는 것이 권장됩니다.
이 flag를 전달하지 않으면 `tty_register_driver()` 과정에서 모든 device도 함께 등록되므로, 이어지는 개별 device 등록 절을 건너뛸 수 있습니다. 그래도 Registering Devices 절의 `struct tty_port` 관련 내용은 여전히 적용됩니다.
driver 등록과 해제 API인 `tty_register_driver`, `tty_unregister_driver`의 kernel-doc은 `drivers/tty/tty_io.c`에서 가져옵니다.
Registration
============
When a struct tty_driver is allocated and filled in, it can be registered using
tty_register_driver(). It is recommended to pass ``TTY_DRIVER_DYNAMIC_DEV`` in
flags of tty_alloc_driver(). If it is not passed, *all* devices are also
registered during tty_register_driver() and the following paragraph of
registering devices can be skipped for such drivers. However, the struct
tty_port part in `Registering Devices`_ is still relevant there.
.. kernel-doc:: drivers/tty/tty_io.c
:identifiers: tty_register_driver tty_unregister_driver
TTY device 등록
57-86모든 TTY device 뒤에는 `struct tty_port`가 있어야 합니다. 일반적으로 TTY driver는 device private structure 안에 `tty_port`를 포함합니다. 자세한 처리는 `tty_port` 문서를 참조하며, `tty_port_get()`과 `tty_port_put()` reference counting 사용이 권장됩니다. 마지막 put은 device private struct를 포함한 `tty_port`를 해제해야 합니다.
원문은 `TTY_DRIVER_DYNAMIC_DEV`를 전달하지 않은 경우 발견한 모든 device를 등록한다고 적지만, 바로 앞 절은 flag를 전달하지 않으면 모든 device가 자동 등록된다고 설명합니다. 전체 문맥과 'the latter is preferred'라는 문구는 동적 device 방식을 사용해 발견한 device를 개별 등록하는 흐름을 권장하는 것으로 읽어야 합니다.
개별 등록에는 `tty_register_device()`를 사용합니다. `struct attribute_group`을 통해 정보를 노출하려면 `tty_register_device_attr()`을 사용합니다. 둘 다 `index`번째 device를 등록하며, 함수가 반환되면 해당 device를 열 수 있습니다.
driver가 비어 있는 index와 올바른 index 선택을 관리합니다. TTY layer는 `tty_alloc_driver()`에 전달한 최대 수보다 많은 device 등록만 거부합니다. 뒤의 Linking Devices to Ports 절에는 더 권장되는 `tty_port` variant가 있습니다.
device를 열면 TTY layer가 `struct tty_struct`를 할당하고 `tty_driver.ops`의 operation을 호출하기 시작합니다. 등록 API `tty_register_device`, `tty_register_device_attr`, `tty_unregister_device`는 `drivers/tty/tty_io.c`에서 문서화합니다.
발견한 device의 port 수명과 등록 이후 open 경로입니다.
Registering Devices
-------------------
Every TTY device shall be backed by a struct tty_port. Usually, TTY drivers
embed tty_port into device's private structures. Further details about handling
tty_port can be found in :doc:`tty_port`. The driver is also recommended to use
tty_port's reference counting by tty_port_get() and tty_port_put(). The final
put is supposed to free the tty_port including the device's private struct.
Unless ``TTY_DRIVER_DYNAMIC_DEV`` was passed as flags to tty_alloc_driver(),
TTY driver is supposed to register every device discovered in the system
(the latter is preferred). This is performed by tty_register_device(). Or by
tty_register_device_attr() if the driver wants to expose some information
through struct attribute_group. Both of them register ``index``'th device and
upon return, the device can be opened. There are also preferred tty_port
variants described in `Linking Devices to Ports`_ later. It is up to driver to
manage free indices and choosing the right one. The TTY layer only refuses to
register more devices than passed to tty_alloc_driver().
When the device is opened, the TTY layer allocates struct tty_struct and starts
calling operations from :c:member:`tty_driver.ops`, see `TTY Operations
Reference`_.
The registration routines are documented as follows:
.. kernel-doc:: drivers/tty/tty_io.c
:identifiers: tty_register_device tty_register_device_attr
tty_unregister_device
----
Device와 `tty_port` 연결
87-110모든 TTY device에는 `struct tty_port`가 지정되어야 하며, 늦어도 `tty_driver.ops.install()` 시점에는 TTY layer가 이를 알아야 합니다.
가장 이상적인 방법은 등록할 때 `tty_register_device()`·`tty_register_device_attr()` 대신 `tty_port_register_device()`·`tty_port_register_device_attr()`을 사용하는 것입니다. 그러면 나중에 driver가 별도로 연결을 관리하지 않아도 됩니다.
그 방법이 불가능하면 실제 등록 전에 `tty_port_link_device()`로 특정 index에 `tty_port`를 연결할 수 있습니다. 이것도 맞지 않으면 마지막 수단으로 `tty_driver.ops.install` hook에서 `tty_port_install()`을 사용할 수 있습니다.
`tty_port_install()` 방식은 주로 PTY처럼 `tty_port`를 요청 시점에 할당하는 in-memory device를 위한 것입니다. 연결 함수 `tty_port_link_device`, `tty_port_register_device`, `tty_port_register_device_attr`은 `drivers/tty/tty_port.c`에서 문서화합니다.
Linking Devices to Ports
------------------------
As stated earlier, every TTY device shall have a struct tty_port assigned to
it. It must be known to the TTY layer at :c:member:`tty_driver.ops.install()`
at latest. There are few helpers to *link* the two. Ideally, the driver uses
tty_port_register_device() or tty_port_register_device_attr() instead of
tty_register_device() and tty_register_device_attr() at the registration time.
This way, the driver needs not care about linking later on.
If that is not possible, the driver still can link the tty_port to a specific
index *before* the actual registration by tty_port_link_device(). If it still
does not fit, tty_port_install() can be used from the
:c:member:`tty_driver.ops.install` hook as a last resort. The last one is
dedicated mostly for in-memory devices like PTY where tty_ports are allocated
on demand.
The linking routines are documented here:
.. kernel-doc:: drivers/tty/tty_port.c
:identifiers: tty_port_link_device tty_port_register_device
tty_port_register_device_attr
----
`struct tty_driver` reference
111-121이 절은 `struct tty_driver`의 모든 member를 문서화하며, 필수 member는 설명 끝에 표시됩니다. 다음 절에서는 `struct tty_operations`를 다룹니다.
구조체 reference는 `include/linux/tty_driver.h`의 `tty_driver` identifier에서 생성됩니다.
TTY Driver Reference
====================
All members of struct tty_driver are documented here. The required members are
noted at the end. struct tty_operations are documented next.
.. kernel-doc:: include/linux/tty_driver.h
:identifiers: tty_driver
----
`struct tty_operations` reference
122-130TTY가 등록되면 TTY layer가 이 driver hook들을 호출할 수 있습니다. operation 집합의 계약은 `include/linux/tty_driver.h`의 `tty_operations` kernel-doc에서 생성됩니다.
TTY Operations Reference
========================
When a TTY is registered, these driver hooks can be invoked by the TTY layer:
.. kernel-doc:: include/linux/tty_driver.h
:identifiers: tty_operations
요약·해설
tty_driver.rst:1-130TTY driver는 최대 device 수와 flags로 `struct tty_driver`를 할당하고 등록합니다. 동적 device 방식에서는 발견한 장치를 `struct tty_port`와 함께 등록하며, port 연결은 등록 시점의 `tty_port_register_device*()`가 가장 권장됩니다. open 이후에는 TTY layer가 `tty_driver.ops`를 호출합니다.