summaryrefslogtreecommitdiffstats
path: root/Documentation/usb/gadget_configfs.rst
blob: e4566ffb223f29a8124f84e94feaf1a7cfc865b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
============================================
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

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.