€•ùÀŒ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/filesystems/sysfs”Œ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/filesystems/sysfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ%/translations/it_IT/filesystems/sysfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ%/translations/ja_JP/filesystems/sysfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ%/translations/ko_KR/filesystems/sysfs”Œ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/filesystems/sysfs”Œ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/filesystems/sysfs”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)�”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…”�”}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³Œ?/var/lib/git/docbuild/linux/Documentation/filesystems/sysfs.rst”h´KubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒ5sysfs - _The_ filesystem for exporting kernel objects”h]”hŒ5sysfs - _The_ filesystem for exporting kernel objects”…”�”}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ paragraph”“”)�”}”(hŒ!Patrick Mochel ”h]”(hŒPatrick Mochel <”…”�”}”(hhßh²hh³Nh´NubhŒ reference”“”)�”}”(hŒmochel@osdl.org”h]”hŒmochel@osdl.org”…”�”}”(hhéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:mochel@osdl.org”uh1hçhhßubhŒ>”…”�”}”(hhßh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhÞ)�”}”(hŒ$Mike Murphy ”h]”(hŒ Mike Murphy <”…”�”}”(hjh²hh³Nh´Nubhè)�”}”(hŒmamurph@cs.clemson.edu”h]”hŒmamurph@cs.clemson.edu”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:mamurph@cs.clemson.edu”uh1hçhjubhŒ>”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hhÊh²hubhŒ field_list”“”)�”}”(hhh]”(hŒfield”“”)�”}”(hhh]”(hŒ field_name”“”)�”}”(hŒRevised”h]”hŒRevised”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j/hj,h³hÇh´KubhŒ field_body”“”)�”}”(hŒ16 August 2011”h]”hÞ)�”}”(hjCh]”hŒ16 August 2011”…”�”}”(hjEh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hjAubah}”(h]”h ]”h"]”h$]”h&]”uh1j?hj,ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j*h³hÇh´K hj'h²hubj+)�”}”(hhh]”(j0)�”}”(hŒOriginal”h]”hŒOriginal”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j/hj^h³hÇh´Kubj@)�”}”(hŒ10 January 2003 ”h]”hÞ)�”}”(hŒ10 January 2003”h]”hŒ10 January 2003”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K hjoubah}”(h]”h ]”h"]”h$]”h&]”uh1j?hj^ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j*h³hÇh´K hj'h²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1j%hhÊh²hh³hÇh´K ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ What it is”h]”hŒ What it is”…”�”}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj“h²hh³hÇh´KubhÞ)�”}”(hŒ­sysfs is a RAM-based filesystem initially based on ramfs. It provides a means to export kernel data structures, their attributes, and the linkages between them to userspace.”h]”hŒ­sysfs is a RAM-based filesystem initially based on ramfs. It provides a means to export kernel data structures, their attributes, and the linkages between them to userspace.”…”�”}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj“h²hubhÞ)�”}”(hŒ�sysfs is tied inherently to the kobject infrastructure. Please read Documentation/core-api/kobject.rst for more information concerning the kobject interface.”h]”hŒ�sysfs is tied inherently to the kobject infrastructure. Please read Documentation/core-api/kobject.rst for more information concerning the kobject interface.”…”�”}”(hj²h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj“h²hubeh}”(h]”Œ what-it-is”ah ]”h"]”Œ what it is”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ Using sysfs”h]”hŒ Using sysfs”…”�”}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjÈh²hh³hÇh´KubhÞ)�”}”(hŒTsysfs is always compiled in if CONFIG_SYSFS is defined. You can access it by doing::”h]”hŒSsysfs is always compiled in if CONFIG_SYSFS is defined. You can access it by doing:”…”�”}”(hjÙh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhjÈh²hubhŒ literal_block”“”)�”}”(hŒmount -t sysfs sysfs /sys”h]”hŒmount -t sysfs sysfs /sys”…”�”}”hjésbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´K!hjÈh²hubeh}”(h]”Œ using-sysfs”ah ]”h"]”Œ using sysfs”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒDirectory Creation”h]”hŒDirectory Creation”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjÿh²hh³hÇh´K%ubhÞ)�”}”(hXWFor every kobject that is registered with the system, a directory is created for it in sysfs. That directory is created as a subdirectory of the kobject's parent, expressing internal object hierarchies to userspace. Top-level directories in sysfs represent the common ancestors of object hierarchies; i.e. the subsystems the objects belong to.”h]”hXYFor every kobject that is registered with the system, a directory is created for it in sysfs. That directory is created as a subdirectory of the kobject’s parent, expressing internal object hierarchies to userspace. Top-level directories in sysfs represent the common ancestors of object hierarchies; i.e. the subsystems the objects belong to.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K'hjÿh²hubhÞ)�”}”(hXœsysfs internally stores a pointer to the kobject that implements a directory in the kernfs_node object associated with the directory. In the past this kobject pointer has been used by sysfs to do reference counting directly on the kobject whenever the file is opened or closed. With the current sysfs implementation the kobject reference count is only modified directly by the function sysfs_schedule_callback().”h]”hXœsysfs internally stores a pointer to the kobject that implements a directory in the kernfs_node object associated with the directory. In the past this kobject pointer has been used by sysfs to do reference counting directly on the kobject whenever the file is opened or closed. With the current sysfs implementation the kobject reference count is only modified directly by the function sysfs_schedule_callback().”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K.hjÿh²hubeh}”(h]”Œdirectory-creation”ah ]”h"]”Œdirectory creation”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K%ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ Attributes”h]”hŒ Attributes”…”�”}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj4h²hh³hÇh´K7ubhÞ)�”}”(hŒØAttributes can be exported for kobjects in the form of regular files in the filesystem. sysfs forwards file I/O operations to methods defined for the attributes, providing a means to read and write kernel attributes.”h]”hŒØAttributes can be exported for kobjects in the form of regular files in the filesystem. sysfs forwards file I/O operations to methods defined for the attributes, providing a means to read and write kernel attributes.”…”�”}”(hjEh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K9hj4h²hubhÞ)�”}”(hŒéAttributes should be ASCII text files, preferably with only one value per file. It is noted that it may not be efficient to contain only one value per file, so it is socially acceptable to express an array of values of the same type.”h]”hŒéAttributes should be ASCII text files, preferably with only one value per file. It is noted that it may not be efficient to contain only one value per file, so it is socially acceptable to express an array of values of the same type.”…”�”}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K>hj4h²hubhÞ)�”}”(hŒÇMixing types, expressing multiple lines of data, and doing fancy formatting of data is heavily frowned upon. Doing these things may get you publicly humiliated and your code rewritten without notice.”h]”hŒÇMixing types, expressing multiple lines of data, and doing fancy formatting of data is heavily frowned upon. Doing these things may get you publicly humiliated and your code rewritten without notice.”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KChj4h²hubhÞ)�”}”(hŒ#An attribute definition is simply::”h]”hŒ"An attribute definition is simply:”…”�”}”(hjoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KHhj4h²hubjè)�”}”(hX'struct attribute { char *name; struct module *owner; umode_t mode; }; int sysfs_create_file(struct kobject * kobj, const struct attribute * attr); void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);”h]”hX'struct attribute { char *name; struct module *owner; umode_t mode; }; int sysfs_create_file(struct kobject * kobj, const struct attribute * attr); void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);”…”�”}”hj}sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´KJhj4h²hubhÞ)�”}”(hŒæA bare attribute contains no means to read or write the value of the attribute. Subsystems are encouraged to define their own attribute structure and wrapper functions for adding and removing attributes for a specific object type.”h]”hŒæA bare attribute contains no means to read or write the value of the attribute. Subsystems are encouraged to define their own attribute structure and wrapper functions for adding and removing attributes for a specific object type.”…”�”}”(hj‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KUhj4h²hubhÞ)�”}”(hŒDFor example, the driver model defines struct device_attribute like::”h]”hŒCFor example, the driver model defines struct device_attribute like:”…”�”}”(hj™h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KZhj4h²hubjè)�”}”(hXÇstruct device_attribute { struct attribute attr; ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf); ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); }; int device_create_file(struct device *, const struct device_attribute *); void device_remove_file(struct device *, const struct device_attribute *);”h]”hXÇstruct device_attribute { struct attribute attr; ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf); ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); }; int device_create_file(struct device *, const struct device_attribute *); void device_remove_file(struct device *, const struct device_attribute *);”…”�”}”hj§sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´K\hj4h²hubhÞ)�”}”(hŒshow) ret = dev_attr->show(dev, dev_attr, buf); if (ret >= (ssize_t)PAGE_SIZE) { printk("dev_attr_show: %pS returned bad count\n", dev_attr->show); } return ret; }”h]”hX`#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct device_attribute *dev_attr = to_dev_attr(attr); struct device *dev = kobj_to_dev(kobj); ssize_t ret = -EIO; if (dev_attr->show) ret = dev_attr->show(dev, dev_attr, buf); if (ret >= (ssize_t)PAGE_SIZE) { printk("dev_attr_show: %pS returned bad count\n", dev_attr->show); } return ret; }”…”�”}”hjœsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´K¯hjEh²hubeh}”(h]”Œsubsystem-specific-callbacks”ah ]”h"]”Œsubsystem-specific callbacks”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K˜ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒReading/Writing Attribute Data”h]”hŒReading/Writing Attribute Data”…”�”}”(hjµh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj²h²hh³hÇh´KÄubhÞ)�”}”(hŒ´To read or write attributes, show() or store() methods must be specified when declaring the attribute. The method types should be as simple as those defined for device attributes::”h]”hŒ³To read or write attributes, show() or store() methods must be specified when declaring the attribute. The method types should be as simple as those defined for device attributes:”…”�”}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÆhj²h²hubjè)�”}”(hŒÂssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf); ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);”h]”hŒÂssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf); ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);”…”�”}”hjÑsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´KÊhj²h²hubhÞ)�”}”(hŒOIOW, they should take only an object, an attribute, and a buffer as parameters.”h]”hŒOIOW, they should take only an object, an attribute, and a buffer as parameters.”…”�”}”(hjßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÎhj²h²hubhÞ)�”}”(hŒËsysfs allocates a buffer of size (PAGE_SIZE) and passes it to the method. sysfs will call the method exactly once for each read or write. This forces the following behavior on the method implementations:”h]”hŒËsysfs allocates a buffer of size (PAGE_SIZE) and passes it to the method. sysfs will call the method exactly once for each read or write. This forces the following behavior on the method implementations:”…”�”}”(hjíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÑhj²h²hubhŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hX³On read(2), the show() method should fill the entire buffer. Recall that an attribute should only be exporting one value, or an array of similar values, so this shouldn't be that expensive. This allows userspace to do partial reads and forward seeks arbitrarily over the entire file at will. If userspace seeks back to zero or does a pread(2) with an offset of '0' the show() method will be called again, rearmed, to fill the buffer. ”h]”(hÞ)�”}”(hŒ½On read(2), the show() method should fill the entire buffer. Recall that an attribute should only be exporting one value, or an array of similar values, so this shouldn't be that expensive.”h]”hŒ¿On read(2), the show() method should fill the entire buffer. Recall that an attribute should only be exporting one value, or an array of similar values, so this shouldn’t be that expensive.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÖhjubhÞ)�”}”(hŒóThis allows userspace to do partial reads and forward seeks arbitrarily over the entire file at will. If userspace seeks back to zero or does a pread(2) with an offset of '0' the show() method will be called again, rearmed, to fill the buffer.”h]”hŒ÷This allows userspace to do partial reads and forward seeks arbitrarily over the entire file at will. If userspace seeks back to zero or does a pread(2) with an offset of ‘0’ the show() method will be called again, rearmed, to fill the buffer.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÚhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhjýh²hh³hÇh´Nubj)�”}”(hXýOn write(2), sysfs expects the entire buffer to be passed during the first write. sysfs then passes the entire buffer to the store() method. A terminating null is added after the data on stores. This makes functions like sysfs_streq() safe to use. When writing sysfs files, userspace processes should first read the entire file, modify the values it wishes to change, then write the entire buffer back. Attribute method implementations should operate on an identical buffer when reading and writing values. ”h]”(hÞ)�”}”(hŒ÷On write(2), sysfs expects the entire buffer to be passed during the first write. sysfs then passes the entire buffer to the store() method. A terminating null is added after the data on stores. This makes functions like sysfs_streq() safe to use.”h]”hŒ÷On write(2), sysfs expects the entire buffer to be passed during the first write. sysfs then passes the entire buffer to the store() method. A terminating null is added after the data on stores. This makes functions like sysfs_streq() safe to use.”…”�”}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kßhj(ubhÞ)�”}”(hŒšWhen writing sysfs files, userspace processes should first read the entire file, modify the values it wishes to change, then write the entire buffer back.”h]”hŒšWhen writing sysfs files, userspace processes should first read the entire file, modify the values it wishes to change, then write the entire buffer back.”…”�”}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kähj(ubhÞ)�”}”(hŒgAttribute method implementations should operate on an identical buffer when reading and writing values.”h]”hŒgAttribute method implementations should operate on an identical buffer when reading and writing values.”…”�”}”(hjHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kèhj(ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhjýh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1jûh³hÇh´KÖhj²h²hubhÞ)�”}”(hŒ Other notes:”h]”hŒ Other notes:”…”�”}”(hjdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Këhj²h²hubjü)�”}”(hhh]”(j)�”}”(hŒTWriting causes the show() method to be rearmed regardless of current file position. ”h]”hÞ)�”}”(hŒSWriting causes the show() method to be rearmed regardless of current file position.”h]”hŒSWriting causes the show() method to be rearmed regardless of current file position.”…”�”}”(hjyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kíhjuubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjrh²hh³hÇh´Nubj)�”}”(hŒKThe buffer will always be PAGE_SIZE bytes in length. On x86, this is 4096. ”h]”hÞ)�”}”(hŒJThe buffer will always be PAGE_SIZE bytes in length. On x86, this is 4096.”h]”hŒJThe buffer will always be PAGE_SIZE bytes in length. On x86, this is 4096.”…”�”}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kðhj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjrh²hh³hÇh´Nubj)�”}”(hŒJshow() methods should return the number of bytes printed into the buffer. ”h]”hÞ)�”}”(hŒIshow() methods should return the number of bytes printed into the buffer.”h]”hŒIshow() methods should return the number of bytes printed into the buffer.”…”�”}”(hj©h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kóhj¥ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjrh²hh³hÇh´Nubj)�”}”(hŒŽNew implementations of show() methods should only use sysfs_emit() or sysfs_emit_at() when formatting the value to be returned to user space. ”h]”hÞ)�”}”(hŒ�New implementations of show() methods should only use sysfs_emit() or sysfs_emit_at() when formatting the value to be returned to user space.”h]”hŒ�New implementations of show() methods should only use sysfs_emit() or sysfs_emit_at() when formatting the value to be returned to user space.”…”�”}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Köhj½ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjrh²hh³hÇh´Nubj)�”}”(hŒ„store() should return the number of bytes used from the buffer. If the entire buffer has been used, just return the count argument. ”h]”hÞ)�”}”(hŒƒstore() should return the number of bytes used from the buffer. If the entire buffer has been used, just return the count argument.”h]”hŒƒstore() should return the number of bytes used from the buffer. If the entire buffer has been used, just return the count argument.”…”�”}”(hjÙh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KùhjÕubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjrh²hh³hÇh´Nubj)�”}”(hŒfshow() or store() can always return errors. If a bad value comes through, be sure to return an error. ”h]”hÞ)�”}”(hŒeshow() or store() can always return errors. If a bad value comes through, be sure to return an error.”h]”hŒeshow() or store() can always return errors. If a bad value comes through, be sure to return an error.”…”�”}”(hjñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kühjíubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjrh²hh³hÇh´Nubj)�”}”(hŒõThe object passed to the methods will be pinned in memory via sysfs reference counting its embedded object. However, the physical entity (e.g. device) the object represents may not be present. Be sure to have a way to check this, if necessary. ”h]”hÞ)�”}”(hŒóThe object passed to the methods will be pinned in memory via sysfs reference counting its embedded object. However, the physical entity (e.g. device) the object represents may not be present. Be sure to have a way to check this, if necessary.”h]”hŒóThe object passed to the methods will be pinned in memory via sysfs reference counting its embedded object. However, the physical entity (e.g. device) the object represents may not be present. Be sure to have a way to check this, if necessary.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kÿhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjrh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jbjcuh1jûh³hÇh´Kíhj²h²hubhÞ)�”}”(hŒCA very simple (and naive) implementation of a device attribute is::”h]”hŒBA very simple (and naive) implementation of a device attribute is:”…”�”}”(hj#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Mhj²h²hubjè)�”}”(hXôstatic ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_emit(buf, "%s\n", dev->name); } static ssize_t store_name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { snprintf(dev->name, sizeof(dev->name), "%.*s", (int)min(count, sizeof(dev->name) - 1), buf); return count; } static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);”h]”hXôstatic ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_emit(buf, "%s\n", dev->name); } static ssize_t store_name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { snprintf(dev->name, sizeof(dev->name), "%.*s", (int)min(count, sizeof(dev->name) - 1), buf); return count; } static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);”…”�”}”hj1sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´Mhj²h²hubhÞ)�”}”(hŒY(Note that the real implementation doesn't allow userspace to set the name for a device.)”h]”hŒ[(Note that the real implementation doesn’t allow userspace to set the name for a device.)”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Mhj²h²hubeh}”(h]”Œreading-writing-attribute-data”ah ]”h"]”Œreading/writing attribute data”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KÄubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒTop Level Directory Layout”h]”hŒTop Level Directory Layout”…”�”}”(hjXh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjUh²hh³hÇh´MubhÞ)�”}”(hŒSThe sysfs directory arrangement exposes the relationship of kernel data structures.”h]”hŒSThe sysfs directory arrangement exposes the relationship of kernel data structures.”…”�”}”(hjfh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MhjUh²hubhÞ)�”}”(hŒ*The top level sysfs directory looks like::”h]”hŒ)The top level sysfs directory looks like:”…”�”}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M"hjUh²hubjè)�”}”(hŒQblock/ bus/ class/ dev/ devices/ firmware/ fs/ hypervisor/ kernel/ module/ power/”h]”hŒQblock/ bus/ class/ dev/ devices/ firmware/ fs/ hypervisor/ kernel/ module/ power/”…”�”}”hj‚sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´M$hjUh²hubhÞ)�”}”(hŒ�devices/ contains a filesystem representation of the device tree. It maps directly to the internal kernel device tree, which is a hierarchy of struct device.”h]”hŒ�devices/ contains a filesystem representation of the device tree. It maps directly to the internal kernel device tree, which is a hierarchy of struct device.”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M0hjUh²hubhÞ)�”}”(hŒ~bus/ contains flat directory layout of the various bus types in the kernel. Each bus's directory contains two subdirectories::”h]”hŒbus/ contains flat directory layout of the various bus types in the kernel. Each bus’s directory contains two subdirectories:”…”�”}”(hjžh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M4hjUh²hubjè)�”}”(hŒdevices/ drivers/”h]”hŒdevices/ drivers/”…”�”}”hj¬sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´M7hjUh²hubhÞ)�”}”(hŒ|devices/ contains symlinks for each device discovered in the system that point to the device's directory under /sys/devices.”h]”hŒ~devices/ contains symlinks for each device discovered in the system that point to the device’s directory under /sys/devices.”…”�”}”(hjºh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M:hjUh²hubhÞ)�”}”(hŒ¢drivers/ contains a directory for each device driver that is loaded for devices on that particular bus (this assumes that drivers do not span multiple bus types).”h]”hŒ¢drivers/ contains a directory for each device driver that is loaded for devices on that particular bus (this assumes that drivers do not span multiple bus types).”…”�”}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M=hjUh²hubhÞ)�”}”(hŒ²fs/ contains a directory for some filesystems. Currently each filesystem wanting to export attributes must create its own hierarchy below fs/ (see fuse/fuse.rst for an example).”h]”hŒ²fs/ contains a directory for some filesystems. Currently each filesystem wanting to export attributes must create its own hierarchy below fs/ (see fuse/fuse.rst for an example).”…”�”}”(hjÖh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MAhjUh²hubhÞ)�”}”(hŒ}module/ contains parameter values and state information for all loaded system modules, for both builtin and loadable modules.”h]”hŒ}module/ contains parameter values and state information for all loaded system modules, for both builtin and loadable modules.”…”�”}”(hjäh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MEhjUh²hubhÞ)�”}”(hX6dev/ contains two directories: char/ and block/. Inside these two directories there are symlinks named :. These symlinks point to the directories under /sys/devices for each device. /sys/dev provides a quick way to lookup the sysfs interface for a device from the result of a stat(2) operation.”h]”hX6dev/ contains two directories: char/ and block/. Inside these two directories there are symlinks named :. These symlinks point to the directories under /sys/devices for each device. /sys/dev provides a quick way to lookup the sysfs interface for a device from the result of a stat(2) operation.”…”�”}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MHhjUh²hubhÞ)�”}”(hŒjMore information on driver-model specific features can be found in Documentation/driver-api/driver-model/.”h]”hŒjMore information on driver-model specific features can be found in Documentation/driver-api/driver-model/.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MNhjUh²hubhÞ)�”}”(hŒƒblock/ contains symlinks to all the block devices discovered on the system. These symlinks point to directories under /sys/devices.”h]”hŒƒblock/ contains symlinks to all the block devices discovered on the system. These symlinks point to directories under /sys/devices.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MQhjUh²hubhÞ)�”}”(hŒ£class/ contains a directory for each device class, grouped by functional type. Each directory in class/ contains symlinks to devices in the /sys/devices directory.”h]”hŒ£class/ contains a directory for each device class, grouped by functional type. Each directory in class/ contains symlinks to devices in the /sys/devices directory.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MThjUh²hubhÞ)�”}”(hŒzfirmware/ contains system firmware data and configuration such as firmware tables, ACPI information, and device tree data.”h]”hŒzfirmware/ contains system firmware data and configuration such as firmware tables, ACPI information, and device tree data.”…”�”}”(hj*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MWhjUh²hubhÞ)�”}”(hŒ§hypervisor/ contains virtualization platform information and provides an interface to the underlying hypervisor. It is only present when running on a virtual machine.”h]”hŒ§hypervisor/ contains virtualization platform information and provides an interface to the underlying hypervisor. It is only present when running on a virtual machine.”…”�”}”(hj8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MZhjUh²hubhÞ)�”}”(hŒOkernel/ contains runtime kernel parameters, configuration settings, and status.”h]”hŒOkernel/ contains runtime kernel parameters, configuration settings, and status.”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M]hjUh²hubhÞ)�”}”(hŒypower/ contains power management subsystem information including sleep states, suspend/resume capabilities, and policies.”h]”hŒypower/ contains power management subsystem information including sleep states, suspend/resume capabilities, and policies.”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M_hjUh²hubeh}”(h]”Œtop-level-directory-layout”ah ]”h"]”Œtop level directory layout”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´MubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒCurrent Interfaces”h]”hŒCurrent Interfaces”…”�”}”(hjmh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjjh²hh³hÇh´MdubhÞ)�”}”(hŒ8The following interface layers currently exist in sysfs.”h]”hŒ8The following interface layers currently exist in sysfs.”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Mfhjjh²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ devices (include/linux/device.h)”h]”hŒ devices (include/linux/device.h)”…”�”}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj‰h²hh³hÇh´MjubhÞ)�”}”(hŒ Structure::”h]”hŒ Structure:”…”�”}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Mkhj‰h²hubjè)�”}”(hX1struct device_attribute { struct attribute attr; ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf); ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); };”h]”hX1struct device_attribute { struct attribute attr; ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf); ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); };”…”�”}”hj¨sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´Mmhj‰h²hubhÞ)�”}”(hŒ Declaring::”h]”hŒ Declaring:”…”�”}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Muhj‰h²hubjè)�”}”(hŒ)DEVICE_ATTR(_name, _mode, _show, _store);”h]”hŒ)DEVICE_ATTR(_name, _mode, _show, _store);”…”�”}”hjÄsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´Mwhj‰h²hubhÞ)�”}”(hŒCreation/Removal::”h]”hŒCreation/Removal:”…”�”}”(hjÒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Myhj‰h²hubjè)�”}”(hŒ¤int device_create_file(struct device *dev, const struct device_attribute * attr); void device_remove_file(struct device *dev, const struct device_attribute * attr);”h]”hŒ¤int device_create_file(struct device *dev, const struct device_attribute * attr); void device_remove_file(struct device *dev, const struct device_attribute * attr);”…”�”}”hjàsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´M{hj‰h²hubeh}”(h]”Œdevices-include-linux-device-h”ah ]”h"]”Œ devices (include/linux/device.h)”ah$]”h&]”uh1hÈhjjh²hh³hÇh´MjubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ$bus drivers (include/linux/device.h)”h]”hŒ$bus drivers (include/linux/device.h)”…”�”}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjöh²hh³hÇh´M€ubhÞ)�”}”(hŒ Structure::”h]”hŒ Structure:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M�hjöh²hubjè)�”}”(hŒÐstruct bus_attribute { struct attribute attr; ssize_t (*show)(const struct bus_type *, char * buf); ssize_t (*store)(const struct bus_type *, const char * buf, size_t count); };”h]”hŒÐstruct bus_attribute { struct attribute attr; ssize_t (*show)(const struct bus_type *, char * buf); ssize_t (*store)(const struct bus_type *, const char * buf, size_t count); };”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´Mƒhjöh²hubhÞ)�”}”(hŒ Declaring::”h]”hŒ Declaring:”…”�”}”(hj#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M‰hjöh²hubjè)�”}”(hŒMstatic BUS_ATTR_RW(name); static BUS_ATTR_RO(name); static BUS_ATTR_WO(name);”h]”hŒMstatic BUS_ATTR_RW(name); static BUS_ATTR_RO(name); static BUS_ATTR_WO(name);”…”�”}”hj1sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´M‹hjöh²hubhÞ)�”}”(hŒCreation/Removal::”h]”hŒCreation/Removal:”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M�hjöh²hubjè)�”}”(hŒ€int bus_create_file(struct bus_type *, struct bus_attribute *); void bus_remove_file(struct bus_type *, struct bus_attribute *);”h]”hŒ€int bus_create_file(struct bus_type *, struct bus_attribute *); void bus_remove_file(struct bus_type *, struct bus_attribute *);”…”�”}”hjMsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´M‘hjöh²hubeh}”(h]”Œ"bus-drivers-include-linux-device-h”ah ]”h"]”Œ$bus drivers (include/linux/device.h)”ah$]”h&]”uh1hÈhjjh²hh³hÇh´M€ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ'device drivers (include/linux/device.h)”h]”hŒ'device drivers (include/linux/device.h)”…”�”}”(hjfh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjch²hh³hÇh´M–ubhÞ)�”}”(hŒ Structure::”h]”hŒ Structure:”…”�”}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M˜hjch²hubjè)�”}”(hŒéstruct driver_attribute { struct attribute attr; ssize_t (*show)(struct device_driver *, char * buf); ssize_t (*store)(struct device_driver *, const char * buf, size_t count); };”h]”hŒéstruct driver_attribute { struct attribute attr; ssize_t (*show)(struct device_driver *, char * buf); ssize_t (*store)(struct device_driver *, const char * buf, size_t count); };”…”�”}”hj‚sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´Mšhjch²hubhÞ)�”}”(hŒ Declaring::”h]”hŒ Declaring:”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M¡hjch²hubjè)�”}”(hŒ+DRIVER_ATTR_RO(_name) DRIVER_ATTR_RW(_name)”h]”hŒ+DRIVER_ATTR_RO(_name) DRIVER_ATTR_RW(_name)”…”�”}”hjžsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´M£hjch²hubhÞ)�”}”(hŒCreation/Removal::”h]”hŒCreation/Removal:”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M¦hjch²hubjè)�”}”(hŒ¢int driver_create_file(struct device_driver *, const struct driver_attribute *); void driver_remove_file(struct device_driver *, const struct driver_attribute *);”h]”hŒ¢int driver_create_file(struct device_driver *, const struct driver_attribute *); void driver_remove_file(struct device_driver *, const struct driver_attribute *);”…”�”}”hjºsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jçh³hÇh´M¨hjch²hubeh}”(h]”Œ%device-drivers-include-linux-device-h”ah ]”h"]”Œ'device drivers (include/linux/device.h)”ah$]”h&]”uh1hÈhjjh²hh³hÇh´M–ubeh}”(h]”Œcurrent-interfaces”ah ]”h"]”Œcurrent interfaces”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´MdubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ Documentation”h]”hŒ Documentation”…”�”}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjØh²hh³hÇh´M­ubhÞ)�”}”(hX>The sysfs directory structure and the attributes in each directory define an ABI between the kernel and user space. As for any ABI, it is important that this ABI is stable and properly documented. All new sysfs attributes must be documented in Documentation/ABI. See also Documentation/ABI/README for more information.”h]”hX>The sysfs directory structure and the attributes in each directory define an ABI between the kernel and user space. As for any ABI, it is important that this ABI is stable and properly documented. All new sysfs attributes must be documented in Documentation/ABI. See also Documentation/ABI/README for more information.”…”�”}”(hjéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M¯hjØh²hubeh}”(h]”Œ documentation”ah ]”h"]”Œ documentation”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´M­ubeh}”(h]”Œ1sysfs-the-filesystem-for-exporting-kernel-objects”ah ]”h"]”Œ5sysfs - _the_ filesystem for exporting kernel objects”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 jÅjÂjüjùj1j.jBj?j¯j¬jRjOjgjdjÕjÒjójðj`j]jÍjÊjüjùuŒ nametypes”}”(j ‰jʼnjü‰j1‰jB‰j¯‰jR‰jg‰jÕ‰jó‰j`‰j͉jü‰uh}”(j hÊjÂj“jùjÈj.jÿj?j4j¬jEjOj²jdjUjÒjjjðj‰j]jöjÊjcjùjØuŒ 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.