123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- Linux USB gadget configured through configfs
- 25th April 2013
- Overview
- ========
- A USB Linux Gadget is a device which has a UDC (USB Device Controller) and can
- be connected to a USB Host to extend it with additional functions like a serial
- port or a mass storage capability.
- A gadget is seen by its host as a set of configurations, each of which contains
- a number of interfaces which, from the gadget's perspective, are known as
- functions, each function representing e.g. a serial connection or a SCSI disk.
- Linux provides a number of functions for gadgets to use.
- Creating a gadget means deciding what configurations there will be
- and which functions each configuration will provide.
- Configfs (please see Documentation/filesystems/configfs/*) lends itself nicely
- for the purpose of telling the kernel about the above mentioned decision.
- This document is about how to do it.
- It also describes how configfs integration into gadget is designed.
- Requirements
- ============
- In order for this to work configfs must be available, so CONFIGFS_FS must be
- 'y' or 'm' in .config. As of this writing USB_LIBCOMPOSITE selects CONFIGFS_FS.
- Usage
- =====
- (The original post describing the first function
- made available through configfs can be seen here:
- http://www.spinics.net/lists/linux-usb/msg76388.html)
- $ modprobe libcomposite
- $ mount none $CONFIGFS_HOME -t configfs
- where CONFIGFS_HOME is the mount point for configfs
- 1. Creating the gadgets
- -----------------------
- For each gadget to be created its corresponding directory must be created:
- $ mkdir $CONFIGFS_HOME/usb_gadget/<gadget name>
- e.g.:
- $ mkdir $CONFIGFS_HOME/usb_gadget/g1
- ...
- ...
- ...
- $ cd $CONFIGFS_HOME/usb_gadget/g1
- Each gadget needs to have its vendor id <VID> and product id <PID> specified:
- $ echo <VID> > idVendor
- $ echo <PID> > idProduct
- A gadget also needs its serial number, manufacturer and product strings.
- In order to have a place to store them, a strings subdirectory must be created
- for each language, e.g.:
- $ mkdir strings/0x409
- Then the strings can be specified:
- $ echo <serial number> > strings/0x409/serialnumber
- $ echo <manufacturer> > strings/0x409/manufacturer
- $ echo <product> > strings/0x409/product
- 2. Creating the configurations
- ------------------------------
- Each gadget will consist of a number of configurations, their corresponding
- directories must be created:
- $ mkdir configs/<name>.<number>
- where <name> can be any string which is legal in a filesystem and the
- <number> is the configuration's number, e.g.:
- $ mkdir configs/c.1
- ...
- ...
- ...
- Each configuration also needs its strings, so a subdirectory must be created
- for each language, e.g.:
- $ mkdir configs/c.1/strings/0x409
- Then the configuration string can be specified:
- $ echo <configuration> > configs/c.1/strings/0x409/configuration
- Some attributes can also be set for a configuration, e.g.:
- $ echo 120 > configs/c.1/MaxPower
- 3. Creating the functions
- -------------------------
- The gadget will provide some functions, for each function its corresponding
- directory must be created:
- $ mkdir functions/<name>.<instance name>
- where <name> corresponds to one of allowed function names and instance name
- is an arbitrary string allowed in a filesystem, e.g.:
- $ mkdir functions/ncm.usb0 # usb_f_ncm.ko gets loaded with request_module()
- ...
- ...
- ...
- Each function provides its specific set of attributes, with either read-only
- or read-write access. Where applicable they need to be written to as
- appropriate.
- Please refer to Documentation/ABI/*/configfs-usb-gadget* for more information.
- 4. Associating the functions with their configurations
- ------------------------------------------------------
- At this moment a number of gadgets is created, each of which has a number of
- configurations specified and a number of functions available. What remains
- is specifying which function is available in which configuration (the same
- function can be used in multiple configurations). This is achieved with
- creating symbolic links:
- $ ln -s functions/<name>.<instance name> configs/<name>.<number>
- e.g.:
- $ ln -s functions/ncm.usb0 configs/c.1
- ...
- ...
- ...
- 5. Enabling the gadget
- ----------------------
- All the above steps serve the purpose of composing the gadget of
- configurations and functions.
- An example directory structure might look like this:
- .
- ./strings
- ./strings/0x409
- ./strings/0x409/serialnumber
- ./strings/0x409/product
- ./strings/0x409/manufacturer
- ./configs
- ./configs/c.1
- ./configs/c.1/ncm.usb0 -> ../../../../usb_gadget/g1/functions/ncm.usb0
- ./configs/c.1/strings
- ./configs/c.1/strings/0x409
- ./configs/c.1/strings/0x409/configuration
- ./configs/c.1/bmAttributes
- ./configs/c.1/MaxPower
- ./functions
- ./functions/ncm.usb0
- ./functions/ncm.usb0/ifname
- ./functions/ncm.usb0/qmult
- ./functions/ncm.usb0/host_addr
- ./functions/ncm.usb0/dev_addr
- ./UDC
- ./bcdUSB
- ./bcdDevice
- ./idProduct
- ./idVendor
- ./bMaxPacketSize0
- ./bDeviceProtocol
- ./bDeviceSubClass
- ./bDeviceClass
- Such a gadget must be finally enabled so that the USB host can enumerate it.
- In order to enable the gadget it must be bound to a UDC (USB Device Controller).
- $ echo <udc name> > UDC
- where <udc name> is one of those found in /sys/class/udc/*
- e.g.:
- $ echo s3c-hsotg > UDC
- 6. Disabling the gadget
- -----------------------
- $ echo "" > UDC
- 7. Cleaning up
- --------------
- Remove functions from configurations:
- $ rm configs/<config name>.<number>/<function>
- where <config name>.<number> specify the configuration and <function> is
- a symlink to a function being removed from the configuration, e.g.:
- $ rm configfs/c.1/ncm.usb0
- ...
- ...
- ...
- Remove strings directories in configurations
- $ rmdir configs/<config name>.<number>/strings/<lang>
- e.g.:
- $ rmdir configs/c.1/strings/0x409
- ...
- ...
- ...
- and remove the configurations
- $ rmdir configs/<config name>.<number>
- e.g.:
- rmdir configs/c.1
- ...
- ...
- ...
- Remove functions (function modules are not unloaded, though)
- $ rmdir functions/<name>.<instance name>
- e.g.:
- $ rmdir functions/ncm.usb0
- ...
- ...
- ...
- Remove strings directories in the gadget
- $ rmdir strings/<lang>
- e.g.:
- $ rmdir strings/0x409
- and finally remove the gadget:
- $ cd ..
- $ rmdir <gadget name>
- e.g.:
- $ rmdir g1
- Implementation design
- =====================
- Below the idea of how configfs works is presented.
- In configfs there are items and groups, both represented as directories.
- The difference between an item and a group is that a group can contain
- other groups. In the picture below only an item is shown.
- Both items and groups can have attributes, which are represented as files.
- The user can create and remove directories, but cannot remove files,
- which can be read-only or read-write, depending on what they represent.
- The filesystem part of configfs operates on config_items/groups and
- configfs_attributes which are generic and of the same type for all
- configured elements. However, they are embedded in usage-specific
- larger structures. In the picture below there is a "cs" which contains
- a config_item and an "sa" which contains a configfs_attribute.
- The filesystem view would be like this:
- ./
- ./cs (directory)
- |
- +--sa (file)
- |
- .
- .
- .
- Whenever a user reads/writes the "sa" file, a function is called
- which accepts a struct config_item and a struct configfs_attribute.
- In the said function the "cs" and "sa" are retrieved using the well
- known container_of technique and an appropriate sa's function (show or
- store) is called and passed the "cs" and a character buffer. The "show"
- is for displaying the file's contents (copy data from the cs to the
- buffer), while the "store" is for modifying the file's contents (copy data
- from the buffer to the cs), but it is up to the implementer of the
- two functions to decide what they actually do.
- typedef struct configured_structure cs;
- typedef struct specific_attribute sa;
- sa
- +----------------------------------+
- cs | (*show)(cs *, buffer); |
- +-----------------+ | (*store)(cs *, buffer, length); |
- | | | |
- | +-------------+ | | +------------------+ |
- | | struct |-|----|------>|struct | |
- | | config_item | | | |configfs_attribute| |
- | +-------------+ | | +------------------+ |
- | | +----------------------------------+
- | data to be set | .
- | | .
- +-----------------+ .
- The file names are decided by the config item/group designer, while
- the directories in general can be named at will. A group can have
- a number of its default sub-groups created automatically.
- For more information on configfs please see
- Documentation/filesystems/configfs/*.
- The concepts described above translate to USB gadgets like this:
- 1. A gadget has its config group, which has some attributes (idVendor,
- idProduct etc) and default sub-groups (configs, functions, strings).
- Writing to the attributes causes the information to be stored in
- appropriate locations. In the configs, functions and strings sub-groups
- a user can create their sub-groups to represent configurations, functions,
- and groups of strings in a given language.
- 2. The user creates configurations and functions, in the configurations
- creates symbolic links to functions. This information is used when the
- gadget's UDC attribute is written to, which means binding the gadget
- to the UDC. The code in drivers/usb/gadget/configfs.c iterates over
- all configurations, and in each configuration it iterates over all
- functions and binds them. This way the whole gadget is bound.
- 3. The file drivers/usb/gadget/configfs.c contains code for
- - gadget's config_group
- - gadget's default groups (configs, functions, strings)
- - associating functions with configurations (symlinks)
- 4. Each USB function naturally has its own view of what it wants
- configured, so config_groups for particular functions are defined
- in the functions implementation files drivers/usb/gadget/f_*.c.
- 5. Function's code is written in such a way that it uses
- usb_get_function_instance(), which, in turn, calls request_module.
- So, provided that modprobe works, modules for particular functions
- are loaded automatically. Please note that the converse is not true:
- after a gadget is disabled and torn down, the modules remain loaded.
|