xref: /OK3568_Linux_fs/kernel/Documentation/usb/functionfs.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun====================
2*4882a593SmuzhiyunHow FunctionFS works
3*4882a593Smuzhiyun====================
4*4882a593Smuzhiyun
5*4882a593SmuzhiyunFrom kernel point of view it is just a composite function with some
6*4882a593Smuzhiyununique behaviour.  It may be added to an USB configuration only after
7*4882a593Smuzhiyunthe user space driver has registered by writing descriptors and
8*4882a593Smuzhiyunstrings (the user space program has to provide the same information
9*4882a593Smuzhiyunthat kernel level composite functions provide when they are added to
10*4882a593Smuzhiyunthe configuration).
11*4882a593Smuzhiyun
12*4882a593SmuzhiyunThis in particular means that the composite initialisation functions
13*4882a593Smuzhiyunmay not be in init section (ie. may not use the __init tag).
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunFrom user space point of view it is a file system which when
16*4882a593Smuzhiyunmounted provides an "ep0" file.  User space driver need to
17*4882a593Smuzhiyunwrite descriptors and strings to that file.  It does not need
18*4882a593Smuzhiyunto worry about endpoints, interfaces or strings numbers but
19*4882a593Smuzhiyunsimply provide descriptors such as if the function was the
20*4882a593Smuzhiyunonly one (endpoints and strings numbers starting from one and
21*4882a593Smuzhiyuninterface numbers starting from zero).  The FunctionFS changes
22*4882a593Smuzhiyunthem as needed also handling situation when numbers differ in
23*4882a593Smuzhiyundifferent configurations.
24*4882a593Smuzhiyun
25*4882a593SmuzhiyunWhen descriptors and strings are written "ep#" files appear
26*4882a593Smuzhiyun(one for each declared endpoint) which handle communication on
27*4882a593Smuzhiyuna single endpoint.  Again, FunctionFS takes care of the real
28*4882a593Smuzhiyunnumbers and changing of the configuration (which means that
29*4882a593Smuzhiyun"ep1" file may be really mapped to (say) endpoint 3 (and when
30*4882a593Smuzhiyunconfiguration changes to (say) endpoint 2)).  "ep0" is used
31*4882a593Smuzhiyunfor receiving events and handling setup requests.
32*4882a593Smuzhiyun
33*4882a593SmuzhiyunWhen all files are closed the function disables itself.
34*4882a593Smuzhiyun
35*4882a593SmuzhiyunWhat I also want to mention is that the FunctionFS is designed in such
36*4882a593Smuzhiyuna way that it is possible to mount it several times so in the end
37*4882a593Smuzhiyuna gadget could use several FunctionFS functions. The idea is that
38*4882a593Smuzhiyuneach FunctionFS instance is identified by the device name used
39*4882a593Smuzhiyunwhen mounting.
40*4882a593Smuzhiyun
41*4882a593SmuzhiyunOne can imagine a gadget that has an Ethernet, MTP and HID interfaces
42*4882a593Smuzhiyunwhere the last two are implemented via FunctionFS.  On user space
43*4882a593Smuzhiyunlevel it would look like this::
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun  $ insmod g_ffs.ko idVendor=<ID> iSerialNumber=<string> functions=mtp,hid
46*4882a593Smuzhiyun  $ mkdir /dev/ffs-mtp && mount -t functionfs mtp /dev/ffs-mtp
47*4882a593Smuzhiyun  $ ( cd /dev/ffs-mtp && mtp-daemon ) &
48*4882a593Smuzhiyun  $ mkdir /dev/ffs-hid && mount -t functionfs hid /dev/ffs-hid
49*4882a593Smuzhiyun  $ ( cd /dev/ffs-hid && hid-daemon ) &
50*4882a593Smuzhiyun
51*4882a593SmuzhiyunOn kernel level the gadget checks ffs_data->dev_name to identify
52*4882a593Smuzhiyunwhether it's FunctionFS designed for MTP ("mtp") or HID ("hid").
53*4882a593Smuzhiyun
54*4882a593SmuzhiyunIf no "functions" module parameters is supplied, the driver accepts
55*4882a593Smuzhiyunjust one function with any name.
56*4882a593Smuzhiyun
57*4882a593SmuzhiyunWhen "functions" module parameter is supplied, only functions
58*4882a593Smuzhiyunwith listed names are accepted. In particular, if the "functions"
59*4882a593Smuzhiyunparameter's value is just a one-element list, then the behaviour
60*4882a593Smuzhiyunis similar to when there is no "functions" at all; however,
61*4882a593Smuzhiyunonly a function with the specified name is accepted.
62*4882a593Smuzhiyun
63*4882a593SmuzhiyunThe gadget is registered only after all the declared function
64*4882a593Smuzhiyunfilesystems have been mounted and USB descriptors of all functions
65*4882a593Smuzhiyunhave been written to their ep0's.
66*4882a593Smuzhiyun
67*4882a593SmuzhiyunConversely, the gadget is unregistered after the first USB function
68*4882a593Smuzhiyuncloses its endpoints.
69