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