€•òœŒsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ'/translations/zh_CN/usb/gadget_configfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/zh_TW/usb/gadget_configfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/it_IT/usb/gadget_configfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/ja_JP/usb/gadget_configfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/ko_KR/usb/gadget_configfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/pt_BR/usb/gadget_configfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/sp_SP/usb/gadget_configfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒ,Linux USB gadget configured through configfs”h]”hŒ,Linux USB gadget configured through configfs”…”�”}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒA/var/lib/git/docbuild/linux/Documentation/usb/gadget_configfs.rst”h´KubhŒ paragraph”“”)�”}”(hŒ25th April 2013”h]”hŒ25th April 2013”…”�”}”(hhÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubh¶)�”}”(hhh]”(h»)�”}”(hŒOverview”h]”hŒOverview”…”�”}”(hhÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhhÛh²hh³hÊh´K ubhÌ)�”}”(hŒÁ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.”h]”hŒÁ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.”…”�”}”(hhìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubhÌ)�”}”(hŒè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.”h]”hŒê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.”…”�”}”(hhúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubhÌ)�”}”(hŒ8Linux provides a number of functions for gadgets to use.”h]”hŒ8Linux provides a number of functions for gadgets to use.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubhÌ)�”}”(hŒwCreating a gadget means deciding what configurations there will be and which functions each configuration will provide.”h]”hŒwCreating a gadget means deciding what configurations there will be and which functions each configuration will provide.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubhÌ)�”}”(hŒÁConfigfs (please see `Documentation/filesystems/configfs.rst`) lends itself nicely for the purpose of telling the kernel about the above mentioned decision. This document is about how to do it.”h]”(hŒConfigfs (please see ”…”�”}”(hj$h²hh³Nh´NubhŒtitle_reference”“”)�”}”(hŒ(`Documentation/filesystems/configfs.rst`”h]”hŒ&Documentation/filesystems/configfs.rst”…”�”}”(hj.h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j,hj$ubhŒ„) lends itself nicely for the purpose of telling the kernel about the above mentioned decision. This document is about how to do it.”…”�”}”(hj$h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubhÌ)�”}”(hŒCIt also describes how configfs integration into gadget is designed.”h]”hŒCIt also describes how configfs integration into gadget is designed.”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubeh}”(h]”Œoverview”ah ]”h"]”Œoverview”ah$]”h&]”uh1hµhh·h²hh³hÊh´K ubh¶)�”}”(hhh]”(h»)�”}”(hŒ Requirements”h]”hŒ Requirements”…”�”}”(hj_h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj\h²hh³hÊh´K%ubhÌ)�”}”(hŒœ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.”h]”hŒ¤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.”…”�”}”(hjmh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K'hj\h²hubeh}”(h]”Œ requirements”ah ]”h"]”Œ requirements”ah$]”h&]”uh1hµhh·h²hh³hÊh´K%ubh¶)�”}”(hhh]”(h»)�”}”(hŒUsage”h]”hŒUsage”…”�”}”(hj†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjƒh²hh³hÊh´K.ubhÌ)�”}”(hŒ˜(The original post describing the first function made available through configfs can be seen here: http://www.spinics.net/lists/linux-usb/msg76388.html)”h]”(hŒc(The original post describing the first function made available through configfs can be seen here: ”…”�”}”(hj”h²hh³Nh´NubhŒ reference”“”)�”}”(hŒ4http://www.spinics.net/lists/linux-usb/msg76388.html”h]”hŒ4http://www.spinics.net/lists/linux-usb/msg76388.html”…”�”}”(hjžh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”j uh1jœhj”ubhŒ)”…”�”}”(hj”h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K0hjƒh²hubhŒ literal_block”“”)�”}”(hŒ?$ modprobe libcomposite $ mount none $CONFIGFS_HOME -t configfs”h]”hŒ?$ modprobe libcomposite $ mount none $CONFIGFS_HOME -t configfs”…”�”}”hj¹sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1j·h³hÊh´K6hjƒh²hubhÌ)�”}”(hŒ3where CONFIGFS_HOME is the mount point for configfs”h]”hŒ3where CONFIGFS_HOME is the mount point for configfs”…”�”}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K9hjƒh²hubh¶)�”}”(hhh]”(h»)�”}”(hŒ1. Creating the gadgets”h]”hŒ1. Creating the gadgets”…”�”}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj×h²hh³hÊh´Khj×h²hubj¸)�”}”(hŒ/$ mkdir $CONFIGFS_HOME/usb_gadget/”h]”hŒ/$ mkdir $CONFIGFS_HOME/usb_gadget/”…”�”}”hjösbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´K@hj×h²hubhÌ)�”}”(hŒe.g.::”h]”hŒe.g.:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KBhj×h²hubj¸)�”}”(hŒT$ mkdir $CONFIGFS_HOME/usb_gadget/g1 ... ... ... $ cd $CONFIGFS_HOME/usb_gadget/g1”h]”hŒT$ mkdir $CONFIGFS_HOME/usb_gadget/g1 ... ... ... $ cd $CONFIGFS_HOME/usb_gadget/g1”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´KDhj×h²hubhÌ)�”}”(hŒNEach gadget needs to have its vendor id and product id specified::”h]”hŒMEach gadget needs to have its vendor id and product id specified:”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KLhj×h²hubj¸)�”}”(hŒ0$ echo > idVendor $ echo > idProduct”h]”hŒ0$ echo > idVendor $ echo > idProduct”…”�”}”hj.sbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´KNhj×h²hubhÌ)�”}”(hŒ±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.::”h]”hŒ°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.:”…”�”}”(hj<h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KQhj×h²hubj¸)�”}”(hŒ$ mkdir strings/0x409”h]”hŒ$ mkdir strings/0x409”…”�”}”hjJsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´KUhj×h²hubhÌ)�”}”(hŒ#Then the strings can be specified::”h]”hŒ"Then the strings can be specified:”…”�”}”(hjXh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KWhj×h²hubj¸)�”}”(hŒ�$ echo > strings/0x409/serialnumber $ echo > strings/0x409/manufacturer $ echo > strings/0x409/product”h]”hŒ�$ echo > strings/0x409/serialnumber $ echo > strings/0x409/manufacturer $ echo > strings/0x409/product”…”�”}”hjfsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´KYhj×h²hubhÌ)�”}”(hŒ¸Further custom string descriptors can be created as directories within the language's directory, with the string text being written to the "s" attribute within the string's directory::”h]”hŒ¿Further custom string descriptors can be created as directories within the language’s directory, with the string text being written to the “sâ€� attribute within the string’s directory:”…”�”}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K]hj×h²hubj¸)�”}”(hŒF$ mkdir strings/0x409/xu.0 $ echo > strings/0x409/xu.0/s”h]”hŒF$ mkdir strings/0x409/xu.0 $ echo > strings/0x409/xu.0/s”…”�”}”hj‚sbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Kahj×h²hubhÌ)�”}”(hŒ•Where function drivers support it, functions may allow symlinks to these custom string descriptors to associate those strings with class descriptors.”h]”hŒ•Where function drivers support it, functions may allow symlinks to these custom string descriptors to associate those strings with class descriptors.”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kdhj×h²hubeh}”(h]”Œcreating-the-gadgets”ah ]”h"]”Œ1. creating the gadgets”ah$]”h&]”uh1hµhjƒh²hh³hÊh´K.”h]”hŒ$ mkdir configs/.”…”�”}”hjÅsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Kmhj¦h²hubhÌ)�”}”(hŒtwhere can be any string which is legal in a filesystem and the is the configuration's number, e.g.::”h]”hŒuwhere can be any string which is legal in a filesystem and the is the configuration’s number, e.g.:”…”�”}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kohj¦h²hubj¸)�”}”(hŒ $ mkdir configs/c.1 ... ... ...”h]”hŒ $ mkdir configs/c.1 ... ... ...”…”�”}”hjásbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Krhj¦h²hubhÌ)�”}”(hŒfEach configuration also needs its strings, so a subdirectory must be created for each language, e.g.::”h]”hŒeEach configuration also needs its strings, so a subdirectory must be created for each language, e.g.:”…”�”}”(hjïh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kxhj¦h²hubj¸)�”}”(hŒ!$ mkdir configs/c.1/strings/0x409”h]”hŒ!$ mkdir configs/c.1/strings/0x409”…”�”}”hjýsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´K{hj¦h²hubhÌ)�”}”(hŒ0Then the configuration string can be specified::”h]”hŒ/Then the configuration string can be specified:”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K}hj¦h²hubj¸)�”}”(hŒ@$ echo > configs/c.1/strings/0x409/configuration”h]”hŒ@$ echo > configs/c.1/strings/0x409/configuration”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Khj¦h²hubhÌ)�”}”(hŒ;Some attributes can also be set for a configuration, e.g.::”h]”hŒ:Some attributes can also be set for a configuration, e.g.:”…”�”}”(hj'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K�hj¦h²hubj¸)�”}”(hŒ!$ echo 120 > configs/c.1/MaxPower”h]”hŒ!$ echo 120 > configs/c.1/MaxPower”…”�”}”hj5sbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Kƒhj¦h²hubeh}”(h]”Œcreating-the-configurations”ah ]”h"]”Œ2. creating the configurations”ah$]”h&]”uh1hµhjƒh²hh³hÊh´Khubh¶)�”}”(hhh]”(h»)�”}”(hŒ3. Creating the functions”h]”hŒ3. Creating the functions”…”�”}”(hjNh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjKh²hh³hÊh´K†ubhÌ)�”}”(hŒgThe gadget will provide some functions, for each function its corresponding directory must be created::”h]”hŒfThe gadget will provide some functions, for each function its corresponding directory must be created:”…”�”}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KˆhjKh²hubj¸)�”}”(hŒ($ mkdir functions/.”h]”hŒ($ mkdir functions/.”…”�”}”hjjsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´K‹hjKh²hubhÌ)�”}”(hŒ‚where corresponds to one of allowed function names and instance name is an arbitrary string allowed in a filesystem, e.g.::”h]”hŒ�where corresponds to one of allowed function names and instance name is an arbitrary string allowed in a filesystem, e.g.:”…”�”}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K�hjKh²hubj¸)�”}”(hŒX$ mkdir functions/ncm.usb0 # usb_f_ncm.ko gets loaded with request_module() ... ... ...”h]”hŒX$ mkdir functions/ncm.usb0 # usb_f_ncm.ko gets loaded with request_module() ... ... ...”…”�”}”hj†sbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´K�hjKh²hubhÌ)�”}”(hŒò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/testing/configfs-usb-gadget for more information.”h]”hŒò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/testing/configfs-usb-gadget for more information.”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K–hjKh²hubeh}”(h]”Œcreating-the-functions”ah ]”h"]”Œ3. creating the functions”ah$]”h&]”uh1hµhjƒh²hh³hÊh´K†ubh¶)�”}”(hhh]”(h»)�”}”(hŒ64. Associating the functions with their configurations”h]”hŒ64. Associating the functions with their configurations”…”�”}”(hj­h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjªh²hh³hÊh´KœubhÌ)�”}”(hXDAt 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::”h]”hXCAt 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:”…”�”}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kžhjªh²hubj¸)�”}”(hŒ@$ ln -s functions/. configs/.”h]”hŒ@$ ln -s functions/. configs/.”…”�”}”hjÉsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´K¤hjªh²hubhÌ)�”}”(hŒe.g.::”h]”hŒe.g.:”…”�”}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¦hjªh²hubj¸)�”}”(hŒ3$ ln -s functions/ncm.usb0 configs/c.1 ... ... ...”h]”hŒ3$ ln -s functions/ncm.usb0 configs/c.1 ... ... ...”…”�”}”hjåsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´K¨hjªh²hubeh}”(h]”Œ3associating-the-functions-with-their-configurations”ah ]”h"]”Œ64. associating the functions with their configurations”ah$]”h&]”uh1hµhjƒh²hh³hÊh´Kœubh¶)�”}”(hhh]”(h»)�”}”(hŒ5. Enabling the gadget”h]”hŒ5. Enabling the gadget”…”�”}”(hjþh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjûh²hh³hÊh´K¯ubhÌ)�”}”(hŒ^All the above steps serve the purpose of composing the gadget of configurations and functions.”h]”hŒ^All the above steps serve the purpose of composing the gadget of configurations and functions.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K±hjûh²hubhÌ)�”}”(hŒ5An example directory structure might look like this::”h]”hŒ4An example directory structure might look like this:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K´hjûh²hubj¸)�”}”(hXf. ./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”h]”hXf. ./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”…”�”}”hj(sbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´K¶hjûh²hubhÌ)�”}”(hŒLSuch a gadget must be finally enabled so that the USB host can enumerate it.”h]”hŒLSuch a gadget must be finally enabled so that the USB host can enumerate it.”…”�”}”(hj6h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÕhjûh²hubhÌ)�”}”(hŒQIn order to enable the gadget it must be bound to a UDC (USB Device Controller)::”h]”hŒPIn order to enable the gadget it must be bound to a UDC (USB Device Controller):”…”�”}”(hjDh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K×hjûh²hubj¸)�”}”(hŒ$ echo > UDC”h]”hŒ$ echo > UDC”…”�”}”hjRsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´KÚhjûh²hubhÌ)�”}”(hŒAwhere is one of those found in /sys/class/udc/* e.g.::”h]”hŒ@where is one of those found in /sys/class/udc/* e.g.:”…”�”}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÜhjûh²hubj¸)�”}”(hŒ$ echo s3c-hsotg > UDC”h]”hŒ$ echo s3c-hsotg > UDC”…”�”}”hjnsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Kßhjûh²hubeh}”(h]”Œenabling-the-gadget”ah ]”h"]”Œ5. enabling the gadget”ah$]”h&]”uh1hµhjƒh²hh³hÊh´K¯ubh¶)�”}”(hhh]”(h»)�”}”(hŒ6. Disabling the gadget”h]”hŒ6. Disabling the gadget”…”�”}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj„h²hh³hÊh´Kãubj¸)�”}”(hŒ$ echo "" > UDC”h]”hŒ$ echo "" > UDC”…”�”}”hj•sbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Kçhj„h²hubeh}”(h]”Œdisabling-the-gadget”ah ]”h"]”Œ6. disabling the gadget”ah$]”h&]”uh1hµhjƒh²hh³hÊh´Kãubh¶)�”}”(hhh]”(h»)�”}”(hŒ7. Cleaning up”h]”hŒ7. Cleaning up”…”�”}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj«h²hh³hÊh´KêubhÌ)�”}”(hŒ&Remove functions from configurations::”h]”hŒ%Remove functions from configurations:”…”�”}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kìhj«h²hubj¸)�”}”(hŒ.$ rm configs/./”h]”hŒ.$ rm configs/./”…”�”}”hjÊsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Kîhj«h²hubhÌ)�”}”(hŒ�where . specify the configuration and is a symlink to a function being removed from the configuration, e.g.::”h]”hŒŒwhere . specify the configuration and is a symlink to a function being removed from the configuration, e.g.:”…”�”}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kðhj«h²hubj¸)�”}”(hŒ&$ rm configs/c.1/ncm.usb0 ... ... ...”h]”hŒ&$ rm configs/c.1/ncm.usb0 ... ... ...”…”�”}”hjæsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Kóhj«h²hubhÌ)�”}”(hŒ.Remove strings directories in configurations::”h]”hŒ-Remove strings directories in configurations:”…”�”}”(hjôh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kùhj«h²hubj¸)�”}”(hŒ5$ rmdir configs/./strings/”h]”hŒ5$ rmdir configs/./strings/”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Kûhj«h²hubhÌ)�”}”(hŒe.g.::”h]”hŒe.g.:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kýhj«h²hubj¸)�”}”(hŒ.$ rmdir configs/c.1/strings/0x409 ... ... ...”h]”hŒ.$ rmdir configs/c.1/strings/0x409 ... ... ...”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Kÿhj«h²hubhÌ)�”}”(hŒand remove the configurations::”h]”hŒand remove the configurations:”…”�”}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj«h²hubj¸)�”}”(hŒ&$ rmdir configs/.”h]”hŒ&$ rmdir configs/.”…”�”}”hj:sbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Mhj«h²hubhÌ)�”}”(hŒe.g.::”h]”hŒe.g.:”…”�”}”(hjHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M hj«h²hubj¸)�”}”(hŒrmdir configs/c.1 ... ... ...”h]”hŒrmdir configs/c.1 ... ... ...”…”�”}”hjVsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´M hj«h²hubhÌ)�”}”(hŒ>Remove functions (function modules are not unloaded, though)::”h]”hŒ=Remove functions (function modules are not unloaded, though):”…”�”}”(hjdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj«h²hubj¸)�”}”(hŒ($ rmdir functions/.”h]”hŒ($ rmdir functions/.”…”�”}”hjrsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Mhj«h²hubhÌ)�”}”(hŒe.g.::”h]”hŒe.g.:”…”�”}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj«h²hubj¸)�”}”(hŒ'$ rmdir functions/ncm.usb0 ... ... ...”h]”hŒ'$ rmdir functions/ncm.usb0 ... ... ...”…”�”}”hjŽsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Mhj«h²hubhÌ)�”}”(hŒ*Remove strings directories in the gadget::”h]”hŒ)Remove strings directories in the gadget:”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj«h²hubj¸)�”}”(hŒ$ rmdir strings/”h]”hŒ$ rmdir strings/”…”�”}”hjªsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´Mhj«h²hubhÌ)�”}”(hŒe.g.::”h]”hŒe.g.:”…”�”}”(hj¸h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M!hj«h²hubj¸)�”}”(hŒ$ rmdir strings/0x409”h]”hŒ$ rmdir strings/0x409”…”�”}”hjÆsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´M#hj«h²hubhÌ)�”}”(hŒand finally remove the gadget::”h]”hŒand finally remove the gadget:”…”�”}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M%hj«h²hubj¸)�”}”(hŒ$ cd .. $ rmdir ”h]”hŒ$ cd .. $ rmdir ”…”�”}”hjâsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´M'hj«h²hubhÌ)�”}”(hŒe.g.::”h]”hŒe.g.:”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M*hj«h²hubj¸)�”}”(hŒ $ rmdir g1”h]”hŒ $ rmdir g1”…”�”}”hjþsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´M,hj«h²hubeh}”(h]”Œ cleaning-up”ah ]”h"]”Œ7. cleaning up”ah$]”h&]”uh1hµhjƒh²hh³hÊh´Kêubeh}”(h]”Œusage”ah ]”h"]”Œusage”ah$]”h&]”uh1hµhh·h²hh³hÊh´K.ubh¶)�”}”(hhh]”(h»)�”}”(hŒImplementation design”h]”hŒImplementation design”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjh²hh³hÊh´M2ubhÌ)�”}”(hXÔ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.”h]”hXÔ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.”…”�”}”(hj-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M4hjh²hubhÌ)�”}”(hXNThe 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.”h]”hXVThe 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.”…”�”}”(hj;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M<hjh²hubhÌ)�”}”(hŒ(The filesystem view would be like this::”h]”hŒ'The filesystem view would be like this:”…”�”}”(hjIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MBhjh²hubj¸)�”}”(hŒF./ ./cs (directory) | +--sa (file) | . . .”h]”hŒF./ ./cs (directory) | +--sa (file) | . . .”…”�”}”hjWsbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´MDhjh²hubhÌ)�”}”(hXXWhenever 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.”h]”hXvWhenever 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.”…”�”}”(hjeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MMhjh²hubj¸)�”}”(hXtypedef 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 | . | | . +-----------------+ .”h]”hXtypedef 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 | . | | . +-----------------+ .”…”�”}”hjssbah}”(h]”h ]”h"]”h$]”h&]”jÇjÈuh1j·h³hÊh´MYhjh²hubhÌ)�”}”(hŒ¿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.”h]”hŒ¿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.”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mjhjh²hubhÌ)�”}”(hŒUFor more information on configfs please see `Documentation/filesystems/configfs.rst`.”h]”(hŒ,For more information on configfs please see ”…”�”}”(hj�h²hh³Nh´Nubj-)�”}”(hŒ(`Documentation/filesystems/configfs.rst`”h]”hŒ&Documentation/filesystems/configfs.rst”…”�”}”(hj—h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j,hj�ubhŒ.”…”�”}”(hj�h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mnhjh²hubhÌ)�”}”(hŒ@The concepts described above translate to USB gadgets like this:”h]”hŒ@The concepts described above translate to USB gadgets like this:”…”�”}”(hj¯h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mqhjh²hubhŒenumerated_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hXˆ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. ”h]”hÌ)�”}”(hX‡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.”h]”hX‡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.”…”�”}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MshjÄubah}”(h]”h ]”h"]”h$]”h&]”uh1jÂhj¿h²hh³hÊh´NubjÃ)�”}”(hX–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. ”h]”hÌ)�”}”(hX•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.”h]”hX—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.”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MzhjÜubah}”(h]”h ]”h"]”h$]”h&]”uh1jÂhj¿h²hh³hÊh´NubjÃ)�”}”(hŒÐ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) ”h]”(hÌ)�”}”(hŒ8The file drivers/usb/gadget/configfs.c contains code for”h]”hŒ8The file drivers/usb/gadget/configfs.c contains code for”…”�”}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M�hjôubhŒ block_quote”“”)�”}”(hŒ‡- gadget's config_group - gadget's default groups (configs, functions, strings) - associating functions with configurations (symlinks) ”h]”hŒ bullet_list”“”)�”}”(hhh]”(jÃ)�”}”(hŒgadget's config_group”h]”hÌ)�”}”(hjh]”hŒgadget’s config_group”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mƒhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÂhjubjÃ)�”}”(hŒ5gadget's default groups (configs, functions, strings)”h]”hÌ)�”}”(hj*h]”hŒ7gadget’s default groups (configs, functions, strings)”…”�”}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M„hj(ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÂhjubjÃ)�”}”(hŒ5associating functions with configurations (symlinks) ”h]”hÌ)�”}”(hŒ4associating functions with configurations (symlinks)”h]”hŒ4associating functions with configurations (symlinks)”…”�”}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M…hj?ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÂhjubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1j h³hÊh´Mƒhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Mƒhjôubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÂhj¿h²hh³hÊh´NubjÃ)�”}”(hŒÀ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. ”h]”hÌ)�”}”(hŒ¿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.”h]”hŒ¿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.”…”�”}”(hjoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M‡hjkubah}”(h]”h ]”h"]”h$]”h&]”uh1jÂhj¿h²hh³hÊh´NubjÃ)�”}”(hXFFunction'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.”h]”hÌ)�”}”(hXFFunction'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.”h]”hXHFunction’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.”…”�”}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M‹hjƒubah}”(h]”h ]”h"]”h$]”h&]”uh1jÂhj¿h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ.”uh1j½hjh²hh³hÊh´Msubeh}”(h]”Œimplementation-design”ah ]”h"]”Œimplementation design”ah$]”h&]”uh1hµhh·h²hh³hÊh´M2ubeh}”(h]”Œ,linux-usb-gadget-configured-through-configfs”ah ]”h"]”Œ,linux usb gadget configured through configfs”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jÙŒerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j³j°jYjVj€j}jjj£j jHjEj§j¤jøjõj�j~j¨j¥jjj«j¨uŒ nametypes”}”(j³‰jY‰j€‰j‰j£‰jH‰j§‰jø‰j�‰j¨‰j‰j«‰uh}”(j°h·jVhÛj}j\jjƒj j×jEj¦j¤jKjõjªj~jûj¥j„jj«j¨juŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.