FunctionFS: enable multiple functions
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Acked-by: Michal Nazarewicz <mina86@mina86.com> Cc: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
304f0b2453
commit
581791f5c7
67
Documentation/usb/functionfs.txt
Normal file
67
Documentation/usb/functionfs.txt
Normal file
@@ -0,0 +1,67 @@
|
||||
*How FunctionFS works*
|
||||
|
||||
From kernel point of view it is just a composite function with some
|
||||
unique behaviour. It may be added to an USB configuration only after
|
||||
the user space driver has registered by writing descriptors and
|
||||
strings (the user space program has to provide the same information
|
||||
that kernel level composite functions provide when they are added to
|
||||
the configuration).
|
||||
|
||||
This in particular means that the composite initialisation functions
|
||||
may not be in init section (ie. may not use the __init tag).
|
||||
|
||||
From user space point of view it is a file system which when
|
||||
mounted provides an "ep0" file. User space driver need to
|
||||
write descriptors and strings to that file. It does not need
|
||||
to worry about endpoints, interfaces or strings numbers but
|
||||
simply provide descriptors such as if the function was the
|
||||
only one (endpoints and strings numbers starting from one and
|
||||
interface numbers starting from zero). The FunctionFS changes
|
||||
them as needed also handling situation when numbers differ in
|
||||
different configurations.
|
||||
|
||||
When descriptors and strings are written "ep#" files appear
|
||||
(one for each declared endpoint) which handle communication on
|
||||
a single endpoint. Again, FunctionFS takes care of the real
|
||||
numbers and changing of the configuration (which means that
|
||||
"ep1" file may be really mapped to (say) endpoint 3 (and when
|
||||
configuration changes to (say) endpoint 2)). "ep0" is used
|
||||
for receiving events and handling setup requests.
|
||||
|
||||
When all files are closed the function disables itself.
|
||||
|
||||
What I also want to mention is that the FunctionFS is designed in such
|
||||
a way that it is possible to mount it several times so in the end
|
||||
a gadget could use several FunctionFS functions. The idea is that
|
||||
each FunctionFS instance is identified by the device name used
|
||||
when mounting.
|
||||
|
||||
One can imagine a gadget that has an Ethernet, MTP and HID interfaces
|
||||
where the last two are implemented via FunctionFS. On user space
|
||||
level it would look like this:
|
||||
|
||||
$ insmod g_ffs.ko idVendor=<ID> iSerialNumber=<string> functions=mtp,hid
|
||||
$ mkdir /dev/ffs-mtp && mount -t functionfs mtp /dev/ffs-mtp
|
||||
$ ( cd /dev/ffs-mtp && mtp-daemon ) &
|
||||
$ mkdir /dev/ffs-hid && mount -t functionfs hid /dev/ffs-hid
|
||||
$ ( cd /dev/ffs-hid && hid-daemon ) &
|
||||
|
||||
On kernel level the gadget checks ffs_data->dev_name to identify
|
||||
whether it's FunctionFS designed for MTP ("mtp") or HID ("hid").
|
||||
|
||||
If no "functions" module parameters is supplied, the driver accepts
|
||||
just one function with any name.
|
||||
|
||||
When "functions" module parameter is supplied, only functions
|
||||
with listed names are accepted. In particular, if the "functions"
|
||||
parameter's value is just a one-element list, then the behaviour
|
||||
is similar to when there is no "functions" at all; however,
|
||||
only a function with the specified name is accepted.
|
||||
|
||||
The gadget is registered only after all the declared function
|
||||
filesystems have been mounted and USB descriptors of all functions
|
||||
have been written to their ep0's.
|
||||
|
||||
Conversely, the gadget is unregistered after the first USB function
|
||||
closes its endpoints.
|
||||
|
Reference in New Issue
Block a user