요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
============================================
Linux USB gadget configured through configfs
============================================
25th April 2013
Overview
========
A USB Linux Gadget is a device which has a UDC (USB Device Controller) and can
be connected to a USB Host to extend it with additional functions like a serial
port or a mass storage capability.
A gadget is seen by its host as a set of configurations, each of which contains
a number of interfaces which, from the gadget's perspective, are known as
functions, each function representing e.g. a serial connection or a SCSI disk.
Linux provides a number of functions for gadgets to use.
Creating a gadget means deciding what configurations there will be
and which functions each configuration will provide.
Configfs (please see `Documentation/filesystems/configfs.rst`) lends itself nicely
for the purpose of telling the kernel about the above mentioned decision.
This document is about how to do it.
It also describes how configfs integration into gadget is designed.
Requirements
============
In order for this to work configfs must be available, so CONFIGFS_FS must be
'y' or 'm' in .config. As of this writing USB_LIBCOMPOSITE selects CONFIGFS_FS.
Usage
=====
(The original post describing the first function
made available through configfs can be seen here:
http://www.spinics.net/lists/linux-usb/msg76388.html)
::
$ modprobe libcomposite
$ mount none $CONFIGFS_HOME -t configfs
where CONFIGFS_HOME is the mount point for configfs
1. Creating the gadgets
-----------------------
For each gadget to be created its corresponding directory must be created::
$ mkdir $CONFIGFS_HOME/usb_gadget/<gadget name>
e.g.::
$ mkdir $CONFIGFS_HOME/usb_gadget/g1
...
...
...
$ cd $CONFIGFS_HOME/usb_gadget/g1
Each gadget needs to have its vendor id <VID> and product id <PID> specified::
$ echo <VID> > idVendor
$ echo <PID> > idProduct
A gadget also needs its serial number, manufacturer and product strings.
In order to have a place to store them, a strings subdirectory must be created
for each language, e.g.::
$ mkdir strings/0x409
Then the strings can be specified::
$ echo <serial number> > strings/0x409/serialnumber
$ echo <manufacturer> > strings/0x409/manufacturer
$ echo <product> > strings/0x409/product
Further custom string descriptors can be created as directories within the
language's directory, with the string text being written to the "s" attribute
within the string's directory::
$ mkdir strings/0x409/xu.0
$ echo <string text> > strings/0x409/xu.0/s
Where function drivers support it, functions may allow symlinks to these custom
string descriptors to associate those strings with class descriptors.
2. Creating the configurations
------------------------------
Each gadget will consist of a number of configurations, their corresponding
directories must be created::
$ mkdir configs/<name>.<number>
where <name> can be any string which is legal in a filesystem and the
<number> is the configuration's number, e.g.::
$ mkdir configs/c.1
...
...
...
Each configuration also needs its strings, so a subdirectory must be created
for each language, e.g.::
$ mkdir configs/c.1/strings/0x409
Then the configuration string can be specified::
$ echo <configuration> > configs/c.1/strings/0x409/configuration
Some attributes can also be set for a configuration, e.g.::
$ echo 120 > configs/c.1/MaxPower
3. Creating the functions
-------------------------
The gadget will provide some functions, for each function its corresponding
directory must be created::
$ mkdir functions/<name>.<instance name>
where <name> corresponds to one of allowed function names and instance name
is an arbitrary string allowed in a filesystem, e.g.::
$ mkdir functions/ncm.usb0 # usb_f_ncm.ko gets loaded with request_module()
...
...
...
Each function provides its specific set of attributes, with either read-only
or read-write access. Where applicable they need to be written to as
appropriate.
Please refer to Documentation/ABI/testing/configfs-usb-gadget for more information.
4. Associating the functions with their configurations
------------------------------------------------------
At this moment a number of gadgets is created, each of which has a number of
configurations specified and a number of functions available. What remains
is specifying which function is available in which configuration (the same
function can be used in multiple configurations). This is achieved with
creating symbolic links::
$ ln -s functions/<name>.<instance name> configs/<name>.<number>
e.g.::
$ ln -s functions/ncm.usb0 configs/c.1
...
...
...
5. Enabling the gadget
----------------------
All the above steps serve the purpose of composing the gadget of
configurations and functions.
An example directory structure might look like this::
.
./strings
./strings/0x409
./strings/0x409/serialnumber
./strings/0x409/product
./strings/0x409/manufacturer
./configs
./configs/c.1
./configs/c.1/ncm.usb0 -> ../../../../usb_gadget/g1/functions/ncm.usb0
./configs/c.1/strings
./configs/c.1/strings/0x409
./configs/c.1/strings/0x409/configuration
./configs/c.1/bmAttributes
./configs/c.1/MaxPower
./functions
./functions/ncm.usb0
./functions/ncm.usb0/ifname
./functions/ncm.usb0/qmult
./functions/ncm.usb0/host_addr
./functions/ncm.usb0/dev_addr
./UDC
./bcdUSB
./bcdDevice
./idProduct
./idVendor
./bMaxPacketSize0
./bDeviceProtocol
./bDeviceSubClass
./bDeviceClass
Such a gadget must be finally enabled so that the USB host can enumerate it.
In order to enable the gadget it must be bound to a UDC (USB Device
Controller)::
$ echo <udc name> > UDC
where <udc name> is one of those found in /sys/class/udc/*
e.g.::
$ echo s3c-hsotg > UDC
6. Disabling the gadget
-----------------------
::
$ echo "" > UDC
7. Cleaning up
--------------
Remove functions from configurations::
$ rm configs/<config name>.<number>/<function>
where <config name>.<number> specify the configuration and <function> is
a symlink to a function being removed from the configuration, e.g.::
$ rm configs/c.1/ncm.usb0
...
...
...
Remove strings directories in configurations::
$ rmdir configs/<config name>.<number>/strings/<lang>
e.g.::
$ rmdir configs/c.1/strings/0x409
...
...
...
and remove the configurations::
$ rmdir configs/<config name>.<number>
e.g.::
rmdir configs/c.1
...
...
...
Remove functions (function modules are not unloaded, though)::
$ rmdir functions/<name>.<instance name>
e.g.::
$ rmdir functions/ncm.usb0
...
...
...
Remove strings directories in the gadget::
$ rmdir strings/<lang>
e.g.::
$ rmdir strings/0x409
and finally remove the gadget::
$ cd ..
$ rmdir <gadget name>
e.g.::
$ rmdir g1
Implementation design
=====================
Below the idea of how configfs works is presented.
In configfs there are items and groups, both represented as directories.
The difference between an item and a group is that a group can contain
other groups. In the picture below only an item is shown.
Both items and groups can have attributes, which are represented as files.
The user can create and remove directories, but cannot remove files,
which can be read-only or read-write, depending on what they represent.
The filesystem part of configfs operates on config_items/groups and
configfs_attributes which are generic and of the same type for all
configured elements. However, they are embedded in usage-specific
larger structures. In the picture below there is a "cs" which contains
a config_item and an "sa" which contains a configfs_attribute.
The filesystem view would be like this::
./
./cs (directory)
|
+--sa (file)
|
.
.
.
Whenever a user reads/writes the "sa" file, a function is called
which accepts a struct config_item and a struct configfs_attribute.
In the said function the "cs" and "sa" are retrieved using the well
known container_of technique and an appropriate sa's function (show or
store) is called and passed the "cs" and a character buffer. The "show"
is for displaying the file's contents (copy data from the cs to the
buffer), while the "store" is for modifying the file's contents (copy data
from the buffer to the cs), but it is up to the implementer of the
two functions to decide what they actually do.
::
typedef struct configured_structure cs;
typedef struct specific_attribute sa;
sa
+----------------------------------+
cs | (*show)(cs *, buffer); |
+-----------------+ | (*store)(cs *, buffer, length); |
| | | |
| +-------------+ | | +------------------+ |
| | struct |-|----|------>|struct | |
| | config_item | | | |configfs_attribute| |
| +-------------+ | | +------------------+ |
| | +----------------------------------+
| data to be set | .
| | .
+-----------------+ .
The file names are decided by the config item/group designer, while
the directories in general can be named at will. A group can have
a number of its default sub-groups created automatically.
For more information on configfs please see
`Documentation/filesystems/configfs.rst`.
The concepts described above translate to USB gadgets like this:
1. A gadget has its config group, which has some attributes (idVendor,
idProduct etc) and default sub-groups (configs, functions, strings).
Writing to the attributes causes the information to be stored in appropriate
locations. In the configs, functions and strings sub-groups a user can
create their sub-groups to represent configurations, functions, and groups
of strings in a given language.
2. The user creates configurations and functions, in the configurations
creates symbolic links to functions. This information is used when the
gadget's UDC attribute is written to, which means binding the gadget to the
UDC. The code in drivers/usb/gadget/configfs.c iterates over all
configurations, and in each configuration it iterates over all functions and
binds them. This way the whole gadget is bound.
3. The file drivers/usb/gadget/configfs.c contains code for
- gadget's config_group
- gadget's default groups (configs, functions, strings)
- associating functions with configurations (symlinks)
4. Each USB function naturally has its own view of what it wants configured, so
config_groups for particular functions are defined in the functions
implementation files drivers/usb/gadget/f_*.c.
5. Function's code is written in such a way that it uses
usb_get_function_instance(), which, in turn, calls request_module. So,
provided that modprobe works, modules for particular functions are loaded
automatically. Please note that the converse is not true: after a gadget is
disabled and torn down, the modules remain loaded.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
제목과 작성일
1-10Configfs를 통해 Linux USB gadget을 구성하는 문서이며 기록된 날짜는 2013년 4월 25일입니다.
============================================
Linux USB gadget configured through configfs
============================================
25th April 2013
Gadget, configuration, function
11-33USB Linux Gadget은 UDC(USB Device Controller)를 갖고 USB host에 연결되어 serial port나 mass storage 같은 기능을 추가하는 device입니다.
Host는 gadget을 configuration 집합으로 봅니다. 각 configuration은 여러 interface를 포함하며 gadget 관점에서는 이를 function이라 부릅니다. Function 하나는 serial 연결이나 SCSI disk 같은 기능을 나타냅니다.
Linux는 gadget이 사용할 여러 function을 제공합니다. Gadget을 만든다는 것은 configuration의 종류와 각 configuration이 제공할 function을 결정하는 일입니다.
Configfs는 이 결정을 kernel에 전달하는 데 적합합니다. 문서는 사용 방법과 gadget의 configfs integration 설계를 함께 설명합니다.
Host가 보는 configuration/interface와 gadget이 구성하는 function 관계입니다.
Overview
========
A USB Linux Gadget is a device which has a UDC (USB Device Controller) and can
be connected to a USB Host to extend it with additional functions like a serial
port or a mass storage capability.
A gadget is seen by its host as a set of configurations, each of which contains
a number of interfaces which, from the gadget's perspective, are known as
functions, each function representing e.g. a serial connection or a SCSI disk.
Linux provides a number of functions for gadgets to use.
Creating a gadget means deciding what configurations there will be
and which functions each configuration will provide.
Configfs (please see `Documentation/filesystems/configfs.rst`) lends itself nicely
for the purpose of telling the kernel about the above mentioned decision.
This document is about how to do it.
It also describes how configfs integration into gadget is designed.
Configfs 요구 사항
34-44Configfs가 사용 가능해야 하므로 `.config`의 `CONFIGFS_FS`가 `y` 또는 `m`이어야 합니다. 문서 작성 당시 `USB_LIBCOMPOSITE`가 `CONFIGFS_FS`를 select합니다.
Requirements
============
In order for this to work configfs must be available, so CONFIGFS_FS must be
'y' or 'm' in .config. As of this writing USB_LIBCOMPOSITE selects CONFIGFS_FS.
libcomposite와 configfs mount
45-58먼저 `modprobe libcomposite`로 module을 load하고 `mount none $CONFIGFS_HOME -t configfs`로 configfs를 mount합니다. `$CONFIGFS_HOME`은 configfs mount point입니다.
Configfs에 처음 공개된 function의 원래 소개 글 URL도 원문에 보존되어 있습니다.
Usage
=====
(The original post describing the first function
made available through configfs can be seen here:
http://www.spinics.net/lists/linux-usb/msg76388.html)
::
$ modprobe libcomposite
$ mount none $CONFIGFS_HOME -t configfs
where CONFIGFS_HOME is the mount point for configfs
Gadget directory, ID, string
59-102Gadget마다 `$CONFIGFS_HOME/usb_gadget/<gadget name>` directory를 만듭니다. 예제 이름은 `g1`이며 이후 그 directory로 이동합니다.
각 gadget의 `idVendor`와 `idProduct`에 VID와 PID를 기록합니다.
Serial number, manufacturer, product string을 저장하려면 language마다 `strings/<lang>` subdirectory를 만듭니다. 예제 language ID `0x409` 아래의 `serialnumber`, `manufacturer`, `product` attribute에 값을 씁니다.
추가 custom string descriptor는 language directory 안에 별도 directory로 만들고 그 안의 `s` attribute에 text를 기록합니다. Function driver가 지원하면 이 custom string으로 symlink를 만들어 class descriptor와 연결할 수 있습니다.
g1 root와 strings/0x409에서 설정하는 항목입니다.
1. Creating the gadgets
-----------------------
For each gadget to be created its corresponding directory must be created::
$ mkdir $CONFIGFS_HOME/usb_gadget/<gadget name>
e.g.::
$ mkdir $CONFIGFS_HOME/usb_gadget/g1
...
...
...
$ cd $CONFIGFS_HOME/usb_gadget/g1
Each gadget needs to have its vendor id <VID> and product id <PID> specified::
$ echo <VID> > idVendor
$ echo <PID> > idProduct
A gadget also needs its serial number, manufacturer and product strings.
In order to have a place to store them, a strings subdirectory must be created
for each language, e.g.::
$ mkdir strings/0x409
Then the strings can be specified::
$ echo <serial number> > strings/0x409/serialnumber
$ echo <manufacturer> > strings/0x409/manufacturer
$ echo <product> > strings/0x409/product
Further custom string descriptors can be created as directories within the
language's directory, with the string text being written to the "s" attribute
within the string's directory::
$ mkdir strings/0x409/xu.0
$ echo <string text> > strings/0x409/xu.0/s
Where function drivers support it, functions may allow symlinks to these custom
string descriptors to associate those strings with class descriptors.
Configuration 생성과 attribute
103-132각 configuration에 `configs/<name>.<number>` directory를 만듭니다. `name`은 filesystem에서 유효한 임의 string이고 `number`는 configuration number이며 예제는 `configs/c.1`입니다.
Configuration도 language별 string directory가 필요합니다. `configs/c.1/strings/0x409/configuration`에 configuration string을 기록합니다.
`configs/c.1/MaxPower` 같은 configuration attribute도 설정할 수 있으며 예제 값은 120입니다.
2. Creating the configurations
------------------------------
Each gadget will consist of a number of configurations, their corresponding
directories must be created::
$ mkdir configs/<name>.<number>
where <name> can be any string which is legal in a filesystem and the
<number> is the configuration's number, e.g.::
$ mkdir configs/c.1
...
...
...
Each configuration also needs its strings, so a subdirectory must be created
for each language, e.g.::
$ mkdir configs/c.1/strings/0x409
Then the configuration string can be specified::
$ echo <configuration> > configs/c.1/strings/0x409/configuration
Some attributes can also be set for a configuration, e.g.::
$ echo 120 > configs/c.1/MaxPower
Function instance 생성
133-154Gadget이 제공할 각 function마다 `functions/<name>.<instance name>` directory를 만듭니다. `name`은 허용된 function 이름이고 instance name은 filesystem에서 유효한 임의 string입니다.
예제 `functions/ncm.usb0`를 만들면 `request_module()`을 통해 `usb_f_ncm.ko`가 load됩니다.
각 function은 read-only 또는 read-write인 고유 attribute 집합을 제공합니다. 자세한 내용은 `Documentation/ABI/testing/configfs-usb-gadget`을 참고합니다.
3. Creating the functions
-------------------------
The gadget will provide some functions, for each function its corresponding
directory must be created::
$ mkdir functions/<name>.<instance name>
where <name> corresponds to one of allowed function names and instance name
is an arbitrary string allowed in a filesystem, e.g.::
$ mkdir functions/ncm.usb0 # usb_f_ncm.ko gets loaded with request_module()
...
...
...
Each function provides its specific set of attributes, with either read-only
or read-write access. Where applicable they need to be written to as
appropriate.
Please refer to Documentation/ABI/testing/configfs-usb-gadget for more information.
Function을 configuration에 연결
155-173생성한 function을 어느 configuration에서 사용할지 symbolic link로 지정합니다. 같은 function을 여러 configuration에서 사용할 수도 있습니다.
`ln -s functions/<name>.<instance name> configs/<name>.<number>` 형식을 사용하며 예제는 `functions/ncm.usb0`를 `configs/c.1`에 연결합니다.
4. Associating the functions with their configurations
------------------------------------------------------
At this moment a number of gadgets is created, each of which has a number of
configurations specified and a number of functions available. What remains
is specifying which function is available in which configuration (the same
function can be used in multiple configurations). This is achieved with
creating symbolic links::
$ ln -s functions/<name>.<instance name> configs/<name>.<number>
e.g.::
$ ln -s functions/ncm.usb0 configs/c.1
...
...
...
Directory 구조와 UDC bind
174-225앞 단계로 gadget의 configuration과 function 구성이 완성됩니다. 원문 directory tree는 gadget string, configuration, NCM function, device descriptor attribute, `UDC` file의 관계를 보여 줍니다.
Host가 enumerate하려면 gadget을 UDC에 bind해야 합니다. `/sys/class/udc/*`에서 controller 이름을 찾아 `UDC` attribute에 씁니다. 예제는 `echo s3c-hsotg > UDC`입니다.
원문의 directory tree를 역할별로 정리한 구조화 도식입니다.
Configfs object 생성부터 host enumeration까지의 순서입니다.
5. Enabling the gadget
----------------------
All the above steps serve the purpose of composing the gadget of
configurations and functions.
An example directory structure might look like this::
.
./strings
./strings/0x409
./strings/0x409/serialnumber
./strings/0x409/product
./strings/0x409/manufacturer
./configs
./configs/c.1
./configs/c.1/ncm.usb0 -> ../../../../usb_gadget/g1/functions/ncm.usb0
./configs/c.1/strings
./configs/c.1/strings/0x409
./configs/c.1/strings/0x409/configuration
./configs/c.1/bmAttributes
./configs/c.1/MaxPower
./functions
./functions/ncm.usb0
./functions/ncm.usb0/ifname
./functions/ncm.usb0/qmult
./functions/ncm.usb0/host_addr
./functions/ncm.usb0/dev_addr
./UDC
./bcdUSB
./bcdDevice
./idProduct
./idVendor
./bMaxPacketSize0
./bDeviceProtocol
./bDeviceSubClass
./bDeviceClass
Such a gadget must be finally enabled so that the USB host can enumerate it.
In order to enable the gadget it must be bound to a UDC (USB Device
Controller)::
$ echo <udc name> > UDC
where <udc name> is one of those found in /sys/class/udc/*
e.g.::
$ echo s3c-hsotg > UDC
Gadget 비활성화
226-232Gadget을 비활성화하려면 빈 string을 `UDC`에 써서 controller binding을 해제합니다: `echo "" > UDC`.
6. Disabling the gadget
-----------------------
::
$ echo "" > UDC
Configuration cleanup
233-272Cleanup은 의존 관계의 역순으로 수행합니다. 먼저 configuration 안의 function symlink를 제거합니다.
그다음 configuration의 language string directory를 제거하고 마지막으로 configuration directory 자체를 제거합니다. 예제에서는 `configs/c.1/ncm.usb0`, `configs/c.1/strings/0x409`, `configs/c.1` 순서입니다.
Bind 해제 뒤 하위 object부터 역순으로 제거합니다.
7. Cleaning up
--------------
Remove functions from configurations::
$ rm configs/<config name>.<number>/<function>
where <config name>.<number> specify the configuration and <function> is
a symlink to a function being removed from the configuration, e.g.::
$ rm configs/c.1/ncm.usb0
...
...
...
Remove strings directories in configurations::
$ rmdir configs/<config name>.<number>/strings/<lang>
e.g.::
$ rmdir configs/c.1/strings/0x409
...
...
...
and remove the configurations::
$ rmdir configs/<config name>.<number>
e.g.::
rmdir configs/c.1
...
...
...
Function, string, gadget 제거
273-304Function instance directory를 제거해도 function module은 unload되지 않습니다. 예제는 `rmdir functions/ncm.usb0`입니다.
Gadget의 language string directory를 제거한 뒤 상위 directory로 이동해 gadget root `g1`을 제거합니다.
Remove functions (function modules are not unloaded, though)::
$ rmdir functions/<name>.<instance name>
e.g.::
$ rmdir functions/ncm.usb0
...
...
...
Remove strings directories in the gadget::
$ rmdir strings/<lang>
e.g.::
$ rmdir strings/0x409
and finally remove the gadget::
$ cd ..
$ rmdir <gadget name>
e.g.::
$ rmdir g1
Configfs item, group, attribute
305-321Configfs에는 directory로 표현되는 item과 group이 있습니다. Group은 다른 group을 포함할 수 있다는 점에서 item과 다릅니다.
Item과 group 모두 file로 표현되는 attribute를 가질 수 있습니다. 사용자는 directory를 생성·제거할 수 있지만 file은 제거할 수 없으며 file은 의미에 따라 read-only 또는 read-write입니다.
Filesystem layer는 모든 구성 요소에 공통인 `config_item`/group과 `configfs_attribute`를 다루지만, 실제로는 용도별 더 큰 structure에 embedded됩니다. 예제의 `cs`는 `config_item`, `sa`는 `configfs_attribute`를 포함합니다.
Generic configfs object와 사용별 container의 관계입니다.
Implementation design
=====================
Below the idea of how configfs works is presented.
In configfs there are items and groups, both represented as directories.
The difference between an item and a group is that a group can contain
other groups. In the picture below only an item is shown.
Both items and groups can have attributes, which are represented as files.
The user can create and remove directories, but cannot remove files,
which can be read-only or read-write, depending on what they represent.
The filesystem part of configfs operates on config_items/groups and
configfs_attributes which are generic and of the same type for all
configured elements. However, they are embedded in usage-specific
larger structures. In the picture below there is a "cs" which contains
a config_item and an "sa" which contains a configfs_attribute.
Filesystem view와 show/store
322-342Filesystem view에서는 `cs`가 directory이고 `sa`가 그 안의 file입니다.
사용자가 `sa` file을 읽거나 쓰면 `struct config_item`과 `struct configfs_attribute`를 받는 function이 호출됩니다. Function은 `container_of`로 바깥의 `cs`와 `sa`를 복원한 뒤 적절한 `show` 또는 `store` callback을 호출합니다.
`show`는 `cs`의 data를 character buffer로 복사해 file 내용을 표시하고, `store`는 buffer의 data를 `cs`로 복사해 내용을 변경합니다. 실제 의미는 callback 구현자가 정합니다.
The filesystem view would be like this::
./
./cs (directory)
|
+--sa (file)
|
.
.
.
Whenever a user reads/writes the "sa" file, a function is called
which accepts a struct config_item and a struct configfs_attribute.
In the said function the "cs" and "sa" are retrieved using the well
known container_of technique and an appropriate sa's function (show or
store) is called and passed the "cs" and a character buffer. The "show"
is for displaying the file's contents (copy data from the cs to the
buffer), while the "store" is for modifying the file's contents (copy data
from the buffer to the cs), but it is up to the implementer of the
two functions to decide what they actually do.
cs와 sa 관계 도식
343-361원문의 ASCII 그림은 configured structure `cs` 내부의 `config_item`과 specific attribute `sa` 내부의 `configfs_attribute` 및 callback 관계를 나타냅니다.
ASCII 구조도를 동일한 의미의 단계형 관계 도식으로 재구성했습니다.
::
typedef struct configured_structure cs;
typedef struct specific_attribute sa;
sa
+----------------------------------+
cs | (*show)(cs *, buffer); |
+-----------------+ | (*store)(cs *, buffer, length); |
| | | |
| +-------------+ | | +------------------+ |
| | struct |-|----|------>|struct | |
| | config_item | | | |configfs_attribute| |
| +-------------+ | | +------------------+ |
| | +----------------------------------+
| data to be set | .
| | .
+-----------------+ .
이름과 default subgroup
362-368File 이름은 config item/group 설계자가 정하고 directory 이름은 일반적으로 사용자가 자유롭게 정할 수 있습니다. Group에는 여러 default subgroup이 자동 생성될 수 있습니다.
Configfs 자체의 자세한 내용은 `Documentation/filesystems/configfs.rst`를 참고합니다.
The file names are decided by the config item/group designer, while
the directories in general can be named at will. A group can have
a number of its default sub-groups created automatically.
For more information on configfs please see
`Documentation/filesystems/configfs.rst`.
Configfs 개념의 USB gadget 대응
369-377Gadget은 `idVendor`, `idProduct` 같은 attribute와 `configs`, `functions`, `strings` default subgroup을 가진 config group입니다.
Attribute write는 적절한 내부 위치에 정보를 저장합니다. 사용자는 default subgroup 아래에 configuration, function, language별 string group을 나타내는 subgroup을 만듭니다.
The concepts described above translate to USB gadgets like this:
1. A gadget has its config group, which has some attributes (idVendor,
idProduct etc) and default sub-groups (configs, functions, strings).
Writing to the attributes causes the information to be stored in appropriate
locations. In the configs, functions and strings sub-groups a user can
create their sub-groups to represent configurations, functions, and groups
of strings in a given language.
UDC write와 전체 function bind
378-384사용자는 configuration과 function을 만들고 configuration 안에 function symlink를 만듭니다.
`UDC` attribute를 쓰면 gadget을 controller에 bind합니다. `drivers/usb/gadget/configfs.c`는 모든 configuration을 순회하고 각 configuration의 모든 function을 순회해 bind하므로 전체 gadget이 결합됩니다.
UDC attribute write가 전체 gadget binding으로 이어지는 구조입니다.
2. The user creates configurations and functions, in the configurations
creates symbolic links to functions. This information is used when the
gadget's UDC attribute is written to, which means binding the gadget to the
UDC. The code in drivers/usb/gadget/configfs.c iterates over all
configurations, and in each configuration it iterates over all functions and
binds them. This way the whole gadget is bound.
Configfs core와 function 구현 파일
385-394`drivers/usb/gadget/configfs.c`에는 gadget config_group, `configs`/`functions`/`strings` default group, symlink를 통한 function-configuration 연결 code가 있습니다.
각 USB function의 고유 설정 view는 해당 function 구현 file `drivers/usb/gadget/f_*.c`에 config_group으로 정의됩니다.
3. The file drivers/usb/gadget/configfs.c contains code for
- gadget's config_group
- gadget's default groups (configs, functions, strings)
- associating functions with configurations (symlinks)
4. Each USB function naturally has its own view of what it wants configured, so
config_groups for particular functions are defined in the functions
implementation files drivers/usb/gadget/f_*.c.
Function module 자동 load와 잔류
395-399Function code는 `usb_get_function_instance()`를 사용하고 이 함수가 `request_module()`을 호출합니다. `modprobe`가 동작하면 특정 function module이 자동으로 load됩니다.
반대 방향은 자동이 아닙니다. Gadget을 disable하고 해체해도 function module은 load된 상태로 남습니다.
5. Function's code is written in such a way that it uses
usb_get_function_instance(), which, in turn, calls request_module. So,
provided that modprobe works, modules for particular functions are loaded
automatically. Please note that the converse is not true: after a gadget is
disabled and torn down, the modules remain loaded.
요약·해설
gadget_configfs.rst:1-399Configfs gadget 구성은 gadget root에서 ID/string을 설정하고 configuration과 function instance를 만든 뒤 symlink로 연결하고 마지막에 `UDC`를 기록하는 순서입니다. 삭제는 반드시 bind 해제 후 역순으로 진행합니다. 내부적으로 generic `config_item`/`configfs_attribute`를 용도별 structure에 embedded하고 `container_of`로 복원해 show/store callback과 USB function bind를 연결합니다.