요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: MC
.. _media_ioc_g_topology:
**************************
ioctl MEDIA_IOC_G_TOPOLOGY
**************************
Name
====
MEDIA_IOC_G_TOPOLOGY - Enumerate the graph topology and graph element properties
Synopsis
========
.. c:macro:: MEDIA_IOC_G_TOPOLOGY
``int ioctl(int fd, MEDIA_IOC_G_TOPOLOGY, struct media_v2_topology *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``argp``
Pointer to struct :c:type:`media_v2_topology`.
Description
===========
The typical usage of this ioctl is to call it twice. On the first call,
the structure defined at struct
:c:type:`media_v2_topology` should be zeroed. At
return, if no errors happen, this ioctl will return the
``topology_version`` and the total number of entities, interfaces, pads
and links.
Before the second call, the userspace should allocate arrays to store
the graph elements that are desired, putting the pointers to them at the
ptr_entities, ptr_interfaces, ptr_links and/or ptr_pads, keeping the
other values untouched.
If the ``topology_version`` remains the same, the ioctl should fill the
desired arrays with the media graph elements.
.. tabularcolumns:: |p{1.6cm}|p{3.4cm}|p{12.3cm}|
.. c:type:: media_v2_topology
.. flat-table:: struct media_v2_topology
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u64
- ``topology_version``
- Version of the media graph topology. When the graph is created,
this field starts with zero. Every time a graph element is added
or removed, this field is incremented.
* - __u32
- ``num_entities``
- Number of entities in the graph
* - __u32
- ``reserved1``
- Applications and drivers shall set this to 0.
* - __u64
- ``ptr_entities``
- A pointer to a memory area where the entities array will be
stored, converted to a 64-bits integer. It can be zero. if zero,
the ioctl won't store the entities. It will just update
``num_entities``
* - __u32
- ``num_interfaces``
- Number of interfaces in the graph
* - __u32
- ``reserved2``
- Applications and drivers shall set this to 0.
* - __u64
- ``ptr_interfaces``
- A pointer to a memory area where the interfaces array will be
stored, converted to a 64-bits integer. It can be zero. if zero,
the ioctl won't store the interfaces. It will just update
``num_interfaces``
* - __u32
- ``num_pads``
- Total number of pads in the graph
* - __u32
- ``reserved3``
- Applications and drivers shall set this to 0.
* - __u64
- ``ptr_pads``
- A pointer to a memory area where the pads array will be stored,
converted to a 64-bits integer. It can be zero. if zero, the ioctl
won't store the pads. It will just update ``num_pads``
* - __u32
- ``num_links``
- Total number of data and interface links in the graph
* - __u32
- ``reserved4``
- Applications and drivers shall set this to 0.
* - __u64
- ``ptr_links``
- A pointer to a memory area where the links array will be stored,
converted to a 64-bits integer. It can be zero. if zero, the ioctl
won't store the links. It will just update ``num_links``
.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.5cm}|
.. c:type:: media_v2_entity
.. flat-table:: struct media_v2_entity
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u32
- ``id``
- Unique ID for the entity. Do not expect that the ID will
always be the same for each instance of the device. In other words,
do not hardcode entity IDs in an application.
* - char
- ``name``\ [64]
- Entity name as an UTF-8 NULL-terminated string. This name must be unique
within the media topology.
* - __u32
- ``function``
- Entity main function, see :ref:`media-entity-functions` for details.
* - __u32
- ``flags``
- Entity flags, see :ref:`media-entity-flag` for details.
Only valid if ``MEDIA_V2_ENTITY_HAS_FLAGS(media_version)``
returns true. The ``media_version`` is defined in struct
:c:type:`media_device_info` and can be retrieved using
:ref:`MEDIA_IOC_DEVICE_INFO`.
* - __u32
- ``reserved``\ [5]
- Reserved for future extensions. Drivers and applications must set
this array to zero.
.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.5cm}|
.. c:type:: media_v2_interface
.. flat-table:: struct media_v2_interface
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u32
- ``id``
- Unique ID for the interface. Do not expect that the ID will
always be the same for each instance of the device. In other words,
do not hardcode interface IDs in an application.
* - __u32
- ``intf_type``
- Interface type, see :ref:`media-intf-type` for details.
* - __u32
- ``flags``
- Interface flags. Currently unused.
* - __u32
- ``reserved``\ [9]
- Reserved for future extensions. Drivers and applications must set
this array to zero.
* - struct media_v2_intf_devnode
- ``devnode``
- Used only for device node interfaces. See
:c:type:`media_v2_intf_devnode` for details.
.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.5cm}|
.. c:type:: media_v2_intf_devnode
.. flat-table:: struct media_v2_intf_devnode
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u32
- ``major``
- Device node major number.
* - __u32
- ``minor``
- Device node minor number.
.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.5cm}|
.. c:type:: media_v2_pad
.. flat-table:: struct media_v2_pad
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u32
- ``id``
- Unique ID for the pad. Do not expect that the ID will
always be the same for each instance of the device. In other words,
do not hardcode pad IDs in an application.
* - __u32
- ``entity_id``
- Unique ID for the entity where this pad belongs.
* - __u32
- ``flags``
- Pad flags, see :ref:`media-pad-flag` for more details.
* - __u32
- ``index``
- Pad index, starts at 0. Only valid if ``MEDIA_V2_PAD_HAS_INDEX(media_version)``
returns true. The ``media_version`` is defined in struct
:c:type:`media_device_info` and can be retrieved using
:ref:`MEDIA_IOC_DEVICE_INFO`.
* - __u32
- ``reserved``\ [4]
- Reserved for future extensions. Drivers and applications must set
this array to zero.
.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.5cm}|
.. c:type:: media_v2_link
.. flat-table:: struct media_v2_link
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u32
- ``id``
- Unique ID for the link. Do not expect that the ID will
always be the same for each instance of the device. In other words,
do not hardcode link IDs in an application.
* - __u32
- ``source_id``
- On pad to pad links: unique ID for the source pad.
On interface to entity links: unique ID for the interface.
* - __u32
- ``sink_id``
- On pad to pad links: unique ID for the sink pad.
On interface to entity links: unique ID for the entity.
* - __u32
- ``flags``
- Link flags, see :ref:`media-link-flag` for more details.
* - __u32
- ``reserved``\ [6]
- Reserved for future extensions. Drivers and applications must set
this array to zero.
Return Value
============
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
ENOSPC
This is returned when either one or more of the num_entities,
num_interfaces, num_links or num_pads are non-zero and are
smaller than the actual number of elements inside the graph. This
may happen if the ``topology_version`` changed when compared to the
last time this ioctl was called. Userspace should usually free the
area for the pointers, zero the struct elements and call this ioctl
again.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
이름, 호출 형식과 인자
1-30`MEDIA_IOC_G_TOPOLOGY`는 media graph topology와 각 graph element의 속성을 열거하는 `MC` namespace ioctl입니다.
int ioctl(int fd, MEDIA_IOC_G_TOPOLOGY, struct media_v2_topology *argp);
Media device의 file descriptor와 topology 교환 구조체를 전달합니다.
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: MC
.. _media_ioc_g_topology:
**************************
ioctl MEDIA_IOC_G_TOPOLOGY
**************************
Name
====
MEDIA_IOC_G_TOPOLOGY - Enumerate the graph topology and graph element properties
Synopsis
========
.. c:macro:: MEDIA_IOC_G_TOPOLOGY
``int ioctl(int fd, MEDIA_IOC_G_TOPOLOGY, struct media_v2_topology *argp)``
Arguments
=========
``fd``
File descriptor returned by :c:func:`open()`.
``argp``
Pointer to struct :c:type:`media_v2_topology`.
두 번 호출하는 열거 절차
31-48이 ioctl의 일반적인 사용법은 두 번 호출하는 것입니다. 첫 호출 전에 `struct media_v2_topology` 전체를 0으로 초기화합니다. 오류가 없다면 첫 호출은 `topology_version`과 entity, interface, pad, link의 전체 개수를 돌려줍니다.
두 번째 호출 전에는 필요한 graph element 배열을 userspace에서 할당하고, 그 주소를 `ptr_entities`, `ptr_interfaces`, `ptr_links`, `ptr_pads` 가운데 원하는 field에 넣습니다. 첫 호출에서 받은 나머지 값은 그대로 유지해야 합니다.
두 호출 사이에 `topology_version`이 그대로라면 두 번째 호출이 요청한 배열을 media graph element로 채웁니다. 버전이 바뀌었다면 개수가 달라졌을 수 있으므로 `ENOSPC` 처리 절차를 따라 다시 시작해야 합니다.
`topology_version`은 첫 호출과 두 번째 호출이 같은 graph 세대를 보았는지 확인하는 일관성 token입니다. 이를 device 재시작 이후에도 유지되는 topology의 영구 식별자로 사용해서는 안 됩니다.
개수 조회와 배열 채우기를 분리하고 topology version으로 두 호출 사이의 변경을 감지합니다.
Description
===========
The typical usage of this ioctl is to call it twice. On the first call,
the structure defined at struct
:c:type:`media_v2_topology` should be zeroed. At
return, if no errors happen, this ioctl will return the
``topology_version`` and the total number of entities, interfaces, pads
and links.
Before the second call, the userspace should allocate arrays to store
the graph elements that are desired, putting the pointers to them at the
ptr_entities, ptr_interfaces, ptr_links and/or ptr_pads, keeping the
other values untouched.
If the ``topology_version`` remains the same, the ioctl should fill the
desired arrays with the media graph elements.
struct media_v2_topology
49-121`struct media_v2_topology`는 topology 세대 번호와 네 종류 element의 개수 및 userspace 배열 주소를 함께 전달합니다. `ptr_*`가 0인 종류는 배열을 쓰지 않고 대응하는 `num_*`만 갱신합니다.
모든 reserved field는 application과 driver가 0으로 설정해야 합니다.
Pointer field를 선택적으로 0으로 둘 수 있으므로 application은 필요한 element 종류만 가져올 수 있습니다. 다만 non-zero `num_*` 값은 제공한 배열의 수용량으로 해석되므로 실제 개수보다 작으면 `ENOSPC`가 발생합니다.
.. tabularcolumns:: |p{1.6cm}|p{3.4cm}|p{12.3cm}|
.. c:type:: media_v2_topology
.. flat-table:: struct media_v2_topology
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u64
- ``topology_version``
- Version of the media graph topology. When the graph is created,
this field starts with zero. Every time a graph element is added
or removed, this field is incremented.
* - __u32
- ``num_entities``
- Number of entities in the graph
* - __u32
- ``reserved1``
- Applications and drivers shall set this to 0.
* - __u64
- ``ptr_entities``
- A pointer to a memory area where the entities array will be
stored, converted to a 64-bits integer. It can be zero. if zero,
the ioctl won't store the entities. It will just update
``num_entities``
* - __u32
- ``num_interfaces``
- Number of interfaces in the graph
* - __u32
- ``reserved2``
- Applications and drivers shall set this to 0.
* - __u64
- ``ptr_interfaces``
- A pointer to a memory area where the interfaces array will be
stored, converted to a 64-bits integer. It can be zero. if zero,
the ioctl won't store the interfaces. It will just update
``num_interfaces``
* - __u32
- ``num_pads``
- Total number of pads in the graph
* - __u32
- ``reserved3``
- Applications and drivers shall set this to 0.
* - __u64
- ``ptr_pads``
- A pointer to a memory area where the pads array will be stored,
converted to a 64-bits integer. It can be zero. if zero, the ioctl
won't store the pads. It will just update ``num_pads``
* - __u32
- ``num_links``
- Total number of data and interface links in the graph
* - __u32
- ``reserved4``
- Applications and drivers shall set this to 0.
* - __u64
- ``ptr_links``
- A pointer to a memory area where the links array will be stored,
converted to a 64-bits integer. It can be zero. if zero, the ioctl
won't store the links. It will just update ``num_links``
struct media_v2_entity
122-158`struct media_v2_entity`는 topology 안의 entity 하나를 설명합니다. `id`는 현재 device instance에서만 의미가 있으므로 application에 고정값으로 넣어서는 안 됩니다.
Entity 이름, 주 기능, 조건부 flag와 확장용 공간을 보존합니다.
`flags`의 유효성 판정에 쓰는 `media_version`은 `struct media_device_info`에 있으며 `MEDIA_IOC_DEVICE_INFO`로 조회합니다. Version gate를 확인하지 않고 flag를 해석하면 오래된 Media API 결과를 잘못 읽을 수 있습니다.
.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.5cm}|
.. c:type:: media_v2_entity
.. flat-table:: struct media_v2_entity
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u32
- ``id``
- Unique ID for the entity. Do not expect that the ID will
always be the same for each instance of the device. In other words,
do not hardcode entity IDs in an application.
* - char
- ``name``\ [64]
- Entity name as an UTF-8 NULL-terminated string. This name must be unique
within the media topology.
* - __u32
- ``function``
- Entity main function, see :ref:`media-entity-functions` for details.
* - __u32
- ``flags``
- Entity flags, see :ref:`media-entity-flag` for details.
Only valid if ``MEDIA_V2_ENTITY_HAS_FLAGS(media_version)``
returns true. The ``media_version`` is defined in struct
:c:type:`media_device_info` and can be retrieved using
:ref:`MEDIA_IOC_DEVICE_INFO`.
* - __u32
- ``reserved``\ [5]
- Reserved for future extensions. Drivers and applications must set
this array to zero.
struct media_v2_interface와 devnode
159-208`struct media_v2_interface`는 userspace가 graph와 상호작용하는 interface를 설명합니다. Interface ID도 device instance 사이에서 안정적이지 않으므로 hardcode해서는 안 됩니다.
Interface 종류와 device node 연결 정보를 제공합니다.
Device node를 식별하는 두 번호입니다.
`devnode`는 모든 interface에 공통으로 해석하는 payload가 아니라 device node interface일 때만 사용하는 값입니다.
.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.5cm}|
.. c:type:: media_v2_interface
.. flat-table:: struct media_v2_interface
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u32
- ``id``
- Unique ID for the interface. Do not expect that the ID will
always be the same for each instance of the device. In other words,
do not hardcode interface IDs in an application.
* - __u32
- ``intf_type``
- Interface type, see :ref:`media-intf-type` for details.
* - __u32
- ``flags``
- Interface flags. Currently unused.
* - __u32
- ``reserved``\ [9]
- Reserved for future extensions. Drivers and applications must set
this array to zero.
* - struct media_v2_intf_devnode
- ``devnode``
- Used only for device node interfaces. See
:c:type:`media_v2_intf_devnode` for details.
.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.5cm}|
.. c:type:: media_v2_intf_devnode
.. flat-table:: struct media_v2_intf_devnode
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u32
- ``major``
- Device node major number.
* - __u32
- ``minor``
- Device node minor number.
struct media_v2_pad
209-243`struct media_v2_pad`는 entity에 속한 연결점을 나타냅니다. Pad ID 역시 device instance마다 달라질 수 있으므로 topology에서 받은 값을 사용해야 합니다.
Pad 소속, 방향 flag, 조건부 index를 함께 전달합니다.
`index`의 version gate에 쓰는 `media_version`도 `struct media_device_info`의 값이며 `MEDIA_IOC_DEVICE_INFO`로 가져옵니다. Gate가 false이면 `index`를 의미 있는 값으로 취급하지 않습니다.
.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.5cm}|
.. c:type:: media_v2_pad
.. flat-table:: struct media_v2_pad
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u32
- ``id``
- Unique ID for the pad. Do not expect that the ID will
always be the same for each instance of the device. In other words,
do not hardcode pad IDs in an application.
* - __u32
- ``entity_id``
- Unique ID for the entity where this pad belongs.
* - __u32
- ``flags``
- Pad flags, see :ref:`media-pad-flag` for more details.
* - __u32
- ``index``
- Pad index, starts at 0. Only valid if ``MEDIA_V2_PAD_HAS_INDEX(media_version)``
returns true. The ``media_version`` is defined in struct
:c:type:`media_device_info` and can be retrieved using
:ref:`MEDIA_IOC_DEVICE_INFO`.
* - __u32
- ``reserved``\ [4]
- Reserved for future extensions. Drivers and applications must set
this array to zero.
struct media_v2_link
244-279`struct media_v2_link`는 pad-to-pad data link와 interface-to-entity link를 같은 구조로 표현합니다. Link 종류에 따라 `source_id`와 `sink_id`가 가리키는 element 종류가 달라집니다.
Source와 sink ID의 의미는 link 종류에 따라 해석합니다.
Application은 link flag와 연결 대상의 ID 집합을 함께 보아 data link인지 interface link인지 구분하고, source와 sink를 올바른 element table에서 찾아야 합니다.
.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.5cm}|
.. c:type:: media_v2_link
.. flat-table:: struct media_v2_link
:header-rows: 0
:stub-columns: 0
:widths: 1 2 8
* - __u32
- ``id``
- Unique ID for the link. Do not expect that the ID will
always be the same for each instance of the device. In other words,
do not hardcode link IDs in an application.
* - __u32
- ``source_id``
- On pad to pad links: unique ID for the source pad.
On interface to entity links: unique ID for the interface.
* - __u32
- ``sink_id``
- On pad to pad links: unique ID for the sink pad.
On interface to entity links: unique ID for the entity.
* - __u32
- ``flags``
- Link flags, see :ref:`media-link-flag` for more details.
* - __u32
- ``reserved``\ [6]
- Reserved for future extensions. Drivers and applications must set
this array to zero.
반환값과 ENOSPC 재시도
280-294성공하면 0을 반환합니다. 오류가 발생하면 -1을 반환하고 `errno`를 알맞게 설정합니다. 공통 오류는 `Generic Error Codes <gen-errors>` 장에서 설명합니다.
`num_entities`, `num_interfaces`, `num_links`, `num_pads` 중 하나 이상이 non-zero이면서 실제 graph element 개수보다 작으면 `ENOSPC`를 반환합니다. 두 호출 사이에 `topology_version`이 바뀌어 graph가 커진 경우 발생할 수 있습니다.
`ENOSPC`를 받으면 userspace는 pointer가 가리키는 기존 배열을 해제하고 structure element를 다시 0으로 만든 뒤 첫 호출부터 반복하는 것이 일반적입니다. 이전 개수나 pointer를 그대로 재사용하면 다시 부족한 buffer를 제출할 수 있습니다.
변경된 topology를 새 snapshot으로 다시 획득합니다.
Return Value
============
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
ENOSPC
This is returned when either one or more of the num_entities,
num_interfaces, num_links or num_pads are non-zero and are
smaller than the actual number of elements inside the graph. This
may happen if the ``topology_version`` changed when compared to the
last time this ioctl was called. Userspace should usually free the
area for the pointers, zero the struct elements and call this ioctl
again.
요약·해설
media-ioc-g-topology.rst:1-294이 ioctl은 먼저 element 개수와 `topology_version`을 읽고, 그 개수에 맞춘 배열 pointer를 넣어 다시 호출하는 snapshot API입니다. ID는 device instance 사이에서 안정적이지 않으며, entity flag와 pad index는 `media_version` gate를 확인해야 합니다. 두 호출 사이 graph가 바뀌어 배열이 작아졌다면 `ENOSPC`를 받고 할당과 조회를 처음부터 반복합니다.