Andrzej Pietrasiewicz | 5e654a4 | 2013-06-13 10:37:25 +0200 | [diff] [blame] | 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | Linux USB gadget configured through configfs |
| 6 | |
| 7 | |
| 8 | 25th April 2013 |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | Overview |
| 14 | ======== |
| 15 | |
| 16 | A USB Linux Gadget is a device which has a UDC (USB Device Controller) and can |
| 17 | be connected to a USB Host to extend it with additional functions like a serial |
| 18 | port or a mass storage capability. |
| 19 | |
| 20 | A gadget is seen by its host as a set of configurations, each of which contains |
| 21 | a number of interfaces which, from the gadget's perspective, are known as |
| 22 | functions, each function representing e.g. a serial connection or a SCSI disk. |
| 23 | |
| 24 | Linux provides a number of functions for gadgets to use. |
| 25 | |
| 26 | Creating a gadget means deciding what configurations there will be |
| 27 | and which functions each configuration will provide. |
| 28 | |
Masanari Iida | 2bb9936 | 2013-10-31 10:57:28 +0900 | [diff] [blame] | 29 | Configfs (please see Documentation/filesystems/configfs/*) lends itself nicely |
Andrzej Pietrasiewicz | 5e654a4 | 2013-06-13 10:37:25 +0200 | [diff] [blame] | 30 | for the purpose of telling the kernel about the above mentioned decision. |
| 31 | This document is about how to do it. |
| 32 | |
| 33 | It also describes how configfs integration into gadget is designed. |
| 34 | |
| 35 | |
| 36 | |
| 37 | |
| 38 | Requirements |
| 39 | ============ |
| 40 | |
| 41 | In order for this to work configfs must be available, so CONFIGFS_FS must be |
| 42 | 'y' or 'm' in .config. As of this writing USB_LIBCOMPOSITE selects CONFIGFS_FS. |
| 43 | |
| 44 | |
| 45 | |
| 46 | |
| 47 | Usage |
| 48 | ===== |
| 49 | |
| 50 | (The original post describing the first function |
| 51 | made available through configfs can be seen here: |
| 52 | http://www.spinics.net/lists/linux-usb/msg76388.html) |
| 53 | |
| 54 | $ modprobe libcomposite |
| 55 | $ mount none $CONFIGFS_HOME -t configfs |
| 56 | |
| 57 | where CONFIGFS_HOME is the mount point for configfs |
| 58 | |
| 59 | 1. Creating the gadgets |
| 60 | ----------------------- |
| 61 | |
| 62 | For each gadget to be created its corresponding directory must be created: |
| 63 | |
| 64 | $ mkdir $CONFIGFS_HOME/usb_gadget/<gadget name> |
| 65 | |
| 66 | e.g.: |
| 67 | |
| 68 | $ mkdir $CONFIGFS_HOME/usb_gadget/g1 |
| 69 | |
| 70 | ... |
| 71 | ... |
| 72 | ... |
| 73 | |
| 74 | $ cd $CONFIGFS_HOME/usb_gadget/g1 |
| 75 | |
| 76 | Each gadget needs to have its vendor id <VID> and product id <PID> specified: |
| 77 | |
| 78 | $ echo <VID> > idVendor |
| 79 | $ echo <PID> > idProduct |
| 80 | |
| 81 | A gadget also needs its serial number, manufacturer and product strings. |
| 82 | In order to have a place to store them, a strings subdirectory must be created |
| 83 | for each language, e.g.: |
| 84 | |
| 85 | $ mkdir strings/0x409 |
| 86 | |
| 87 | Then the strings can be specified: |
| 88 | |
| 89 | $ echo <serial number> > strings/0x409/serialnumber |
| 90 | $ echo <manufacturer> > strings/0x409/manufacturer |
| 91 | $ echo <product> > strings/0x409/product |
| 92 | |
| 93 | 2. Creating the configurations |
| 94 | ------------------------------ |
| 95 | |
| 96 | Each gadget will consist of a number of configurations, their corresponding |
| 97 | directories must be created: |
| 98 | |
| 99 | $ mkdir configs/<name>.<number> |
| 100 | |
| 101 | where <name> can be any string which is legal in a filesystem and the |
Masanari Iida | 2bb9936 | 2013-10-31 10:57:28 +0900 | [diff] [blame] | 102 | <number> is the configuration's number, e.g.: |
Andrzej Pietrasiewicz | 5e654a4 | 2013-06-13 10:37:25 +0200 | [diff] [blame] | 103 | |
| 104 | $ mkdir configs/c.1 |
| 105 | |
| 106 | ... |
| 107 | ... |
| 108 | ... |
| 109 | |
| 110 | Each configuration also needs its strings, so a subdirectory must be created |
| 111 | for each language, e.g.: |
| 112 | |
| 113 | $ mkdir configs/c.1/strings/0x409 |
| 114 | |
| 115 | Then the configuration string can be specified: |
| 116 | |
| 117 | $ echo <configuration> > configs/c.1/strings/0x409/configuration |
| 118 | |
| 119 | Some attributes can also be set for a configuration, e.g.: |
| 120 | |
| 121 | $ echo 120 > configs/c.1/MaxPower |
| 122 | |
| 123 | 3. Creating the functions |
| 124 | ------------------------- |
| 125 | |
| 126 | The gadget will provide some functions, for each function its corresponding |
| 127 | directory must be created: |
| 128 | |
| 129 | $ mkdir functions/<name>.<instance name> |
| 130 | |
| 131 | where <name> corresponds to one of allowed function names and instance name |
| 132 | is an arbitrary string allowed in a filesystem, e.g.: |
| 133 | |
| 134 | $ mkdir functions/ncm.usb0 # usb_f_ncm.ko gets loaded with request_module() |
| 135 | |
| 136 | ... |
| 137 | ... |
| 138 | ... |
| 139 | |
| 140 | Each function provides its specific set of attributes, with either read-only |
| 141 | or read-write access. Where applicable they need to be written to as |
| 142 | appropriate. |
| 143 | Please refer to Documentation/ABI/*/configfs-usb-gadget* for more information. |
| 144 | |
| 145 | 4. Associating the functions with their configurations |
| 146 | ------------------------------------------------------ |
| 147 | |
| 148 | At this moment a number of gadgets is created, each of which has a number of |
| 149 | configurations specified and a number of functions available. What remains |
| 150 | is specifying which function is available in which configuration (the same |
| 151 | function can be used in multiple configurations). This is achieved with |
| 152 | creating symbolic links: |
| 153 | |
| 154 | $ ln -s functions/<name>.<instance name> configs/<name>.<number> |
| 155 | |
| 156 | e.g.: |
| 157 | |
| 158 | $ ln -s functions/ncm.usb0 configs/c.1 |
| 159 | |
| 160 | ... |
| 161 | ... |
| 162 | ... |
| 163 | |
| 164 | 5. Enabling the gadget |
| 165 | ---------------------- |
| 166 | |
| 167 | All the above steps serve the purpose of composing the gadget of |
| 168 | configurations and functions. |
| 169 | |
| 170 | An example directory structure might look like this: |
| 171 | |
| 172 | . |
| 173 | ./strings |
| 174 | ./strings/0x409 |
| 175 | ./strings/0x409/serialnumber |
| 176 | ./strings/0x409/product |
| 177 | ./strings/0x409/manufacturer |
| 178 | ./configs |
| 179 | ./configs/c.1 |
| 180 | ./configs/c.1/ncm.usb0 -> ../../../../usb_gadget/g1/functions/ncm.usb0 |
| 181 | ./configs/c.1/strings |
| 182 | ./configs/c.1/strings/0x409 |
| 183 | ./configs/c.1/strings/0x409/configuration |
| 184 | ./configs/c.1/bmAttributes |
| 185 | ./configs/c.1/MaxPower |
| 186 | ./functions |
| 187 | ./functions/ncm.usb0 |
| 188 | ./functions/ncm.usb0/ifname |
| 189 | ./functions/ncm.usb0/qmult |
| 190 | ./functions/ncm.usb0/host_addr |
| 191 | ./functions/ncm.usb0/dev_addr |
| 192 | ./UDC |
| 193 | ./bcdUSB |
| 194 | ./bcdDevice |
| 195 | ./idProduct |
| 196 | ./idVendor |
| 197 | ./bMaxPacketSize0 |
| 198 | ./bDeviceProtocol |
| 199 | ./bDeviceSubClass |
| 200 | ./bDeviceClass |
| 201 | |
| 202 | |
| 203 | Such a gadget must be finally enabled so that the USB host can enumerate it. |
| 204 | In order to enable the gadget it must be bound to a UDC (USB Device Controller). |
| 205 | |
| 206 | $ echo <udc name> > UDC |
| 207 | |
| 208 | where <udc name> is one of those found in /sys/class/udc/* |
| 209 | e.g.: |
| 210 | |
| 211 | $ echo s3c-hsotg > UDC |
| 212 | |
| 213 | |
| 214 | 6. Disabling the gadget |
| 215 | ----------------------- |
| 216 | |
| 217 | $ echo "" > UDC |
| 218 | |
| 219 | 7. Cleaning up |
| 220 | -------------- |
| 221 | |
| 222 | Remove functions from configurations: |
| 223 | |
| 224 | $ rm configs/<config name>.<number>/<function> |
| 225 | |
| 226 | where <config name>.<number> specify the configuration and <function> is |
| 227 | a symlink to a function being removed from the configuration, e.g.: |
| 228 | |
| 229 | $ rm configfs/c.1/ncm.usb0 |
| 230 | |
| 231 | ... |
| 232 | ... |
| 233 | ... |
| 234 | |
| 235 | Remove strings directories in configurations |
| 236 | |
| 237 | $ rmdir configs/<config name>.<number>/strings/<lang> |
| 238 | |
| 239 | e.g.: |
| 240 | |
| 241 | $ rmdir configs/c.1/strings/0x409 |
| 242 | |
| 243 | ... |
| 244 | ... |
| 245 | ... |
| 246 | |
| 247 | and remove the configurations |
| 248 | |
| 249 | $ rmdir configs/<config name>.<number> |
| 250 | |
| 251 | e.g.: |
| 252 | |
| 253 | rmdir configs/c.1 |
| 254 | |
| 255 | ... |
| 256 | ... |
| 257 | ... |
| 258 | |
| 259 | Remove functions (function modules are not unloaded, though) |
| 260 | |
| 261 | $ rmdir functions/<name>.<instance name> |
| 262 | |
| 263 | e.g.: |
| 264 | |
| 265 | $ rmdir functions/ncm.usb0 |
| 266 | |
| 267 | ... |
| 268 | ... |
| 269 | ... |
| 270 | |
| 271 | Remove strings directories in the gadget |
| 272 | |
| 273 | $ rmdir strings/<lang> |
| 274 | |
| 275 | e.g.: |
| 276 | |
| 277 | $ rmdir strings/0x409 |
| 278 | |
| 279 | and finally remove the gadget: |
| 280 | |
| 281 | $ cd .. |
| 282 | $ rmdir <gadget name> |
| 283 | |
| 284 | e.g.: |
| 285 | |
| 286 | $ rmdir g1 |
| 287 | |
| 288 | |
| 289 | |
| 290 | |
| 291 | Implementation design |
| 292 | ===================== |
| 293 | |
| 294 | Below the idea of how configfs works is presented. |
| 295 | In configfs there are items and groups, both represented as directories. |
| 296 | The difference between an item and a group is that a group can contain |
| 297 | other groups. In the picture below only an item is shown. |
| 298 | Both items and groups can have attributes, which are represented as files. |
| 299 | The user can create and remove directories, but cannot remove files, |
| 300 | which can be read-only or read-write, depending on what they represent. |
| 301 | |
| 302 | The filesystem part of configfs operates on config_items/groups and |
| 303 | configfs_attributes which are generic and of the same type for all |
| 304 | configured elements. However, they are embedded in usage-specific |
| 305 | larger structures. In the picture below there is a "cs" which contains |
| 306 | a config_item and an "sa" which contains a configfs_attribute. |
| 307 | |
| 308 | The filesystem view would be like this: |
| 309 | |
| 310 | ./ |
| 311 | ./cs (directory) |
| 312 | | |
| 313 | +--sa (file) |
| 314 | | |
| 315 | . |
| 316 | . |
| 317 | . |
| 318 | |
| 319 | Whenever a user reads/writes the "sa" file, a function is called |
| 320 | which accepts a struct config_item and a struct configfs_attribute. |
| 321 | In the said function the "cs" and "sa" are retrieved using the well |
| 322 | known container_of technique and an appropriate sa's function (show or |
| 323 | store) is called and passed the "cs" and a character buffer. The "show" |
| 324 | is for displaying the file's contents (copy data from the cs to the |
| 325 | buffer), while the "store" is for modifying the file's contents (copy data |
| 326 | from the buffer to the cs), but it is up to the implementer of the |
| 327 | two functions to decide what they actually do. |
| 328 | |
| 329 | typedef struct configured_structure cs; |
Masanari Iida | 2bb9936 | 2013-10-31 10:57:28 +0900 | [diff] [blame] | 330 | typedef struct specific_attribute sa; |
Andrzej Pietrasiewicz | 5e654a4 | 2013-06-13 10:37:25 +0200 | [diff] [blame] | 331 | |
| 332 | sa |
| 333 | +----------------------------------+ |
| 334 | cs | (*show)(cs *, buffer); | |
| 335 | +-----------------+ | (*store)(cs *, buffer, length); | |
| 336 | | | | | |
| 337 | | +-------------+ | | +------------------+ | |
| 338 | | | struct |-|----|------>|struct | | |
| 339 | | | config_item | | | |configfs_attribute| | |
| 340 | | +-------------+ | | +------------------+ | |
| 341 | | | +----------------------------------+ |
| 342 | | data to be set | . |
| 343 | | | . |
| 344 | +-----------------+ . |
| 345 | |
| 346 | The file names are decided by the config item/group designer, while |
| 347 | the directories in general can be named at will. A group can have |
| 348 | a number of its default sub-groups created automatically. |
| 349 | |
| 350 | For more information on configfs please see |
| 351 | Documentation/filesystems/configfs/*. |
| 352 | |
| 353 | The concepts described above translate to USB gadgets like this: |
| 354 | |
| 355 | 1. A gadget has its config group, which has some attributes (idVendor, |
| 356 | idProduct etc) and default sub-groups (configs, functions, strings). |
| 357 | Writing to the attributes causes the information to be stored in |
| 358 | appropriate locations. In the configs, functions and strings sub-groups |
| 359 | a user can create their sub-groups to represent configurations, functions, |
| 360 | and groups of strings in a given language. |
| 361 | |
| 362 | 2. The user creates configurations and functions, in the configurations |
| 363 | creates symbolic links to functions. This information is used when the |
| 364 | gadget's UDC attribute is written to, which means binding the gadget |
| 365 | to the UDC. The code in drivers/usb/gadget/configfs.c iterates over |
| 366 | all configurations, and in each configuration it iterates over all |
| 367 | functions and binds them. This way the whole gadget is bound. |
| 368 | |
| 369 | 3. The file drivers/usb/gadget/configfs.c contains code for |
| 370 | |
| 371 | - gadget's config_group |
| 372 | - gadget's default groups (configs, functions, strings) |
| 373 | - associating functions with configurations (symlinks) |
| 374 | |
| 375 | 4. Each USB function naturally has its own view of what it wants |
| 376 | configured, so config_groups for particular functions are defined |
| 377 | in the functions implementation files drivers/usb/gadget/f_*.c. |
| 378 | |
Frans Klaver | 720a8d3 | 2014-10-01 15:30:31 +0200 | [diff] [blame] | 379 | 5. Function's code is written in such a way that it uses |
Andrzej Pietrasiewicz | 5e654a4 | 2013-06-13 10:37:25 +0200 | [diff] [blame] | 380 | |
| 381 | usb_get_function_instance(), which, in turn, calls request_module. |
| 382 | So, provided that modprobe works, modules for particular functions |
| 383 | are loaded automatically. Please note that the converse is not true: |
| 384 | after a gadget is disabled and torn down, the modules remain loaded. |