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