18c2ecf20Sopenharmony_ci====================
28c2ecf20Sopenharmony_ciHow FunctionFS works
38c2ecf20Sopenharmony_ci====================
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ciFrom kernel point of view it is just a composite function with some
68c2ecf20Sopenharmony_ciunique behaviour.  It may be added to an USB configuration only after
78c2ecf20Sopenharmony_cithe user space driver has registered by writing descriptors and
88c2ecf20Sopenharmony_cistrings (the user space program has to provide the same information
98c2ecf20Sopenharmony_cithat kernel level composite functions provide when they are added to
108c2ecf20Sopenharmony_cithe configuration).
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ciThis in particular means that the composite initialisation functions
138c2ecf20Sopenharmony_cimay not be in init section (ie. may not use the __init tag).
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ciFrom user space point of view it is a file system which when
168c2ecf20Sopenharmony_cimounted provides an "ep0" file.  User space driver need to
178c2ecf20Sopenharmony_ciwrite descriptors and strings to that file.  It does not need
188c2ecf20Sopenharmony_cito worry about endpoints, interfaces or strings numbers but
198c2ecf20Sopenharmony_cisimply provide descriptors such as if the function was the
208c2ecf20Sopenharmony_cionly one (endpoints and strings numbers starting from one and
218c2ecf20Sopenharmony_ciinterface numbers starting from zero).  The FunctionFS changes
228c2ecf20Sopenharmony_cithem as needed also handling situation when numbers differ in
238c2ecf20Sopenharmony_cidifferent configurations.
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ciWhen descriptors and strings are written "ep#" files appear
268c2ecf20Sopenharmony_ci(one for each declared endpoint) which handle communication on
278c2ecf20Sopenharmony_cia single endpoint.  Again, FunctionFS takes care of the real
288c2ecf20Sopenharmony_cinumbers and changing of the configuration (which means that
298c2ecf20Sopenharmony_ci"ep1" file may be really mapped to (say) endpoint 3 (and when
308c2ecf20Sopenharmony_ciconfiguration changes to (say) endpoint 2)).  "ep0" is used
318c2ecf20Sopenharmony_cifor receiving events and handling setup requests.
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ciWhen all files are closed the function disables itself.
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ciWhat I also want to mention is that the FunctionFS is designed in such
368c2ecf20Sopenharmony_cia way that it is possible to mount it several times so in the end
378c2ecf20Sopenharmony_cia gadget could use several FunctionFS functions. The idea is that
388c2ecf20Sopenharmony_cieach FunctionFS instance is identified by the device name used
398c2ecf20Sopenharmony_ciwhen mounting.
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciOne can imagine a gadget that has an Ethernet, MTP and HID interfaces
428c2ecf20Sopenharmony_ciwhere the last two are implemented via FunctionFS.  On user space
438c2ecf20Sopenharmony_cilevel it would look like this::
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci  $ insmod g_ffs.ko idVendor=<ID> iSerialNumber=<string> functions=mtp,hid
468c2ecf20Sopenharmony_ci  $ mkdir /dev/ffs-mtp && mount -t functionfs mtp /dev/ffs-mtp
478c2ecf20Sopenharmony_ci  $ ( cd /dev/ffs-mtp && mtp-daemon ) &
488c2ecf20Sopenharmony_ci  $ mkdir /dev/ffs-hid && mount -t functionfs hid /dev/ffs-hid
498c2ecf20Sopenharmony_ci  $ ( cd /dev/ffs-hid && hid-daemon ) &
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ciOn kernel level the gadget checks ffs_data->dev_name to identify
528c2ecf20Sopenharmony_ciwhether it's FunctionFS designed for MTP ("mtp") or HID ("hid").
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ciIf no "functions" module parameters is supplied, the driver accepts
558c2ecf20Sopenharmony_cijust one function with any name.
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ciWhen "functions" module parameter is supplied, only functions
588c2ecf20Sopenharmony_ciwith listed names are accepted. In particular, if the "functions"
598c2ecf20Sopenharmony_ciparameter's value is just a one-element list, then the behaviour
608c2ecf20Sopenharmony_ciis similar to when there is no "functions" at all; however,
618c2ecf20Sopenharmony_cionly a function with the specified name is accepted.
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ciThe gadget is registered only after all the declared function
648c2ecf20Sopenharmony_cifilesystems have been mounted and USB descriptors of all functions
658c2ecf20Sopenharmony_cihave been written to their ep0's.
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ciConversely, the gadget is unregistered after the first USB function
688c2ecf20Sopenharmony_cicloses its endpoints.
69