Back to home page

OSCL-LXR

 
 

    


0001 ====================
0002 How FunctionFS works
0003 ====================
0004 
0005 From kernel point of view it is just a composite function with some
0006 unique behaviour.  It may be added to an USB configuration only after
0007 the user space driver has registered by writing descriptors and
0008 strings (the user space program has to provide the same information
0009 that kernel level composite functions provide when they are added to
0010 the configuration).
0011 
0012 This in particular means that the composite initialisation functions
0013 may not be in init section (ie. may not use the __init tag).
0014 
0015 From user space point of view it is a file system which when
0016 mounted provides an "ep0" file.  User space driver need to
0017 write descriptors and strings to that file.  It does not need
0018 to worry about endpoints, interfaces or strings numbers but
0019 simply provide descriptors such as if the function was the
0020 only one (endpoints and strings numbers starting from one and
0021 interface numbers starting from zero).  The FunctionFS changes
0022 them as needed also handling situation when numbers differ in
0023 different configurations.
0024 
0025 When descriptors and strings are written "ep#" files appear
0026 (one for each declared endpoint) which handle communication on
0027 a single endpoint.  Again, FunctionFS takes care of the real
0028 numbers and changing of the configuration (which means that
0029 "ep1" file may be really mapped to (say) endpoint 3 (and when
0030 configuration changes to (say) endpoint 2)).  "ep0" is used
0031 for receiving events and handling setup requests.
0032 
0033 When all files are closed the function disables itself.
0034 
0035 What I also want to mention is that the FunctionFS is designed in such
0036 a way that it is possible to mount it several times so in the end
0037 a gadget could use several FunctionFS functions. The idea is that
0038 each FunctionFS instance is identified by the device name used
0039 when mounting.
0040 
0041 One can imagine a gadget that has an Ethernet, MTP and HID interfaces
0042 where the last two are implemented via FunctionFS.  On user space
0043 level it would look like this::
0044 
0045   $ insmod g_ffs.ko idVendor=<ID> iSerialNumber=<string> functions=mtp,hid
0046   $ mkdir /dev/ffs-mtp && mount -t functionfs mtp /dev/ffs-mtp
0047   $ ( cd /dev/ffs-mtp && mtp-daemon ) &
0048   $ mkdir /dev/ffs-hid && mount -t functionfs hid /dev/ffs-hid
0049   $ ( cd /dev/ffs-hid && hid-daemon ) &
0050 
0051 On kernel level the gadget checks ffs_data->dev_name to identify
0052 whether it's FunctionFS designed for MTP ("mtp") or HID ("hid").
0053 
0054 If no "functions" module parameters is supplied, the driver accepts
0055 just one function with any name.
0056 
0057 When "functions" module parameter is supplied, only functions
0058 with listed names are accepted. In particular, if the "functions"
0059 parameter's value is just a one-element list, then the behaviour
0060 is similar to when there is no "functions" at all; however,
0061 only a function with the specified name is accepted.
0062 
0063 The gadget is registered only after all the declared function
0064 filesystems have been mounted and USB descriptors of all functions
0065 have been written to their ep0's.
0066 
0067 Conversely, the gadget is unregistered after the first USB function
0068 closes its endpoints.