sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget1/translations/zh_CN/driver-api/firmware/fw_uploadmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget1/translations/zh_TW/driver-api/firmware/fw_uploadmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget1/translations/it_IT/driver-api/firmware/fw_uploadmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget1/translations/ja_JP/driver-api/firmware/fw_uploadmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget1/translations/ko_KR/driver-api/firmware/fw_uploadmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget1/translations/sp_SP/driver-api/firmware/fw_uploadmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhK/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload.rsthKubhsection)}(hhh](htitle)}(hFirmware Upload APIh]hFirmware Upload API}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hXA device driver that registers with the firmware loader will expose persistent sysfs nodes to enable users to initiate firmware updates for that device. It is the responsibility of the device driver and/or the device itself to perform any validation on the data received. Firmware upload uses the same *loading* and *data* sysfs files described in the documentation for firmware fallback. It also adds additional sysfs files to provide status on the transfer of the firmware image to the device.h](hX/A device driver that registers with the firmware loader will expose persistent sysfs nodes to enable users to initiate firmware updates for that device. It is the responsibility of the device driver and/or the device itself to perform any validation on the data received. Firmware upload uses the same }(hhhhhNhNubhemphasis)}(h *loading*h]hloading}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh and }(hhhhhNhNubh)}(h*data*h]hdata}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh sysfs files described in the documentation for firmware fallback. It also adds additional sysfs files to provide status on the transfer of the firmware image to the device.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(hRegister for firmware uploadh]hRegister for firmware upload}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hXEA device driver registers for firmware upload by calling firmware_upload_register(). Among the parameter list is a name to identify the device under /sys/class/firmware. A user may initiate a firmware upload by echoing a 1 to the *loading* sysfs file for the target device. Next, the user writes the firmware image to the *data* sysfs file. After writing the firmware data, the user echos 0 to the *loading* sysfs file to signal completion. Echoing 0 to *loading* also triggers the transfer of the firmware to the lower-lever device driver in the context of a kernel worker thread.h](hA device driver registers for firmware upload by calling firmware_upload_register(). Among the parameter list is a name to identify the device under /sys/class/firmware. A user may initiate a firmware upload by echoing a 1 to the }(hjhhhNhNubh)}(h *loading*h]hloading}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhS sysfs file for the target device. Next, the user writes the firmware image to the }(hjhhhNhNubh)}(h*data*h]hdata}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhF sysfs file. After writing the firmware data, the user echos 0 to the }(hjhhhNhNubh)}(h *loading*h]hloading}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh/ sysfs file to signal completion. Echoing 0 to }(hjhhhNhNubh)}(h *loading*h]hloading}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhv also triggers the transfer of the firmware to the lower-lever device driver in the context of a kernel worker thread.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hTo use the firmware upload API, write a driver that implements a set of ops. The probe function calls firmware_upload_register() and the remove function calls firmware_upload_unregister() such as::h]hTo use the firmware upload API, write a driver that implements a set of ops. The probe function calls firmware_upload_register() and the remove function calls firmware_upload_unregister() such as:}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh literal_block)}(hXstatic const struct fw_upload_ops m10bmc_ops = { .prepare = m10bmc_sec_prepare, .write = m10bmc_sec_write, .poll_complete = m10bmc_sec_poll_complete, .cancel = m10bmc_sec_cancel, .cleanup = m10bmc_sec_cleanup, }; static int m10bmc_sec_probe(struct platform_device *pdev) { const char *fw_name, *truncate; struct m10bmc_sec *sec; struct fw_upload *fwl; unsigned int len; sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL); if (!sec) return -ENOMEM; sec->dev = &pdev->dev; sec->m10bmc = dev_get_drvdata(pdev->dev.parent); dev_set_drvdata(&pdev->dev, sec); fw_name = dev_name(sec->dev); truncate = strstr(fw_name, ".auto"); len = (truncate) ? truncate - fw_name : strlen(fw_name); sec->fw_name = kmemdup_nul(fw_name, len, GFP_KERNEL); fwl = firmware_upload_register(THIS_MODULE, sec->dev, sec->fw_name, &m10bmc_ops, sec); if (IS_ERR(fwl)) { dev_err(sec->dev, "Firmware Upload driver failed to start\n"); kfree(sec->fw_name); return PTR_ERR(fwl); } sec->fwl = fwl; return 0; } static int m10bmc_sec_remove(struct platform_device *pdev) { struct m10bmc_sec *sec = dev_get_drvdata(&pdev->dev); firmware_upload_unregister(sec->fwl); kfree(sec->fw_name); return 0; }h]hXstatic const struct fw_upload_ops m10bmc_ops = { .prepare = m10bmc_sec_prepare, .write = m10bmc_sec_write, .poll_complete = m10bmc_sec_poll_complete, .cancel = m10bmc_sec_cancel, .cleanup = m10bmc_sec_cleanup, }; static int m10bmc_sec_probe(struct platform_device *pdev) { const char *fw_name, *truncate; struct m10bmc_sec *sec; struct fw_upload *fwl; unsigned int len; sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL); if (!sec) return -ENOMEM; sec->dev = &pdev->dev; sec->m10bmc = dev_get_drvdata(pdev->dev.parent); dev_set_drvdata(&pdev->dev, sec); fw_name = dev_name(sec->dev); truncate = strstr(fw_name, ".auto"); len = (truncate) ? truncate - fw_name : strlen(fw_name); sec->fw_name = kmemdup_nul(fw_name, len, GFP_KERNEL); fwl = firmware_upload_register(THIS_MODULE, sec->dev, sec->fw_name, &m10bmc_ops, sec); if (IS_ERR(fwl)) { dev_err(sec->dev, "Firmware Upload driver failed to start\n"); kfree(sec->fw_name); return PTR_ERR(fwl); } sec->fwl = fwl; return 0; } static int m10bmc_sec_remove(struct platform_device *pdev) { struct m10bmc_sec *sec = dev_get_drvdata(&pdev->dev); firmware_upload_unregister(sec->fwl); kfree(sec->fw_name); return 0; }}hjvsbah}(h]h ]h"]h$]h&]hhuh1jthhhK hhhhubh)}(hhh](h)}(hfirmware_upload_registerh]hfirmware_upload_register}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKRubhindex)}(hhh]h}(h]h ]h"]h$]h&]entries](single%firmware_upload_register (C function)c.firmware_upload_registerhNtauh1jhjhhhNhNubhdesc)}(hhh](hdesc_signature)}(hstruct fw_upload * firmware_upload_register (struct module *module, struct device *parent, const char *name, const struct fw_upload_ops *ops, void *dd_handle)h]hdesc_signature_line)}(hstruct fw_upload *firmware_upload_register(struct module *module, struct device *parent, const char *name, const struct fw_upload_ops *ops, void *dd_handle)h](hdesc_sig_keyword)}(hstructh]hstruct}(hjhhhNhNubah}(h]h ]kah"]h$]h&]uh1jhjhhhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chM#ubhdesc_sig_space)}(h h]h }(hjhhhNhNubah}(h]h ]wah"]h$]h&]uh1jhjhhhjhM#ubh)}(hhh]h desc_sig_name)}(h fw_uploadh]h fw_upload}(hjhhhNhNubah}(h]h ]nah"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&] refdomaincreftype identifier reftargetjmodnameN classnameN c:parent_keysphinx.domains.c LookupKey)}data]j ASTIdentifier)}jfirmware_upload_registersbc.firmware_upload_registerasbuh1hhjhhhjhM#ubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhhjhM#ubhdesc_sig_punctuation)}(h*h]h*}(hjhhhNhNubah}(h]h ]pah"]h$]h&]uh1jhjhhhjhM#ubh desc_name)}(hfirmware_upload_registerh]j)}(hjh]hfirmware_upload_register}(hj/hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj+ubah}(h]h ](sig-namedescnameeh"]h$]h&]hhuh1j)hjhhhjhM#ubhdesc_parameterlist)}(hr(struct module *module, struct device *parent, const char *name, const struct fw_upload_ops *ops, void *dd_handle)h](hdesc_parameter)}(hstruct module *moduleh](j)}(hjh]hstruct}(hjPhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubj)}(h h]h }(hj]hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubh)}(hhh]j)}(hmoduleh]hmodule}(hjnhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjkubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjpmodnameN classnameNjj)}j]jc.firmware_upload_registerasbuh1hhjLubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjLubj)}(hmoduleh]hmodule}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjLubeh}(h]h ]h"]h$]h&]noemphhhuh1jJhjFubjK)}(hstruct device *parenth](j)}(hjh]hstruct}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubh)}(hhh]j)}(hdeviceh]hdevice}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jc.firmware_upload_registerasbuh1hhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(hjh]h*}(hj hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubj)}(hparenth]hparent}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jJhjFubjK)}(hconst char *nameh](j)}(hconsth]hconst}(hj0hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj,ubj)}(h h]h }(hj>hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj,ubhdesc_sig_keyword_type)}(hcharh]hchar}(hjNhhhNhNubah}(h]h ]ktah"]h$]h&]uh1jLhj,ubj)}(h h]h }(hj]hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj,ubj)}(hjh]h*}(hjkhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhj,ubj)}(hnameh]hname}(hjxhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj,ubeh}(h]h ]h"]h$]h&]noemphhhuh1jJhjFubjK)}(hconst struct fw_upload_ops *opsh](j)}(hj2h]hconst}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(hjh]hstruct}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubh)}(hhh]j)}(h fw_upload_opsh]h fw_upload_ops}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jc.firmware_upload_registerasbuh1hhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubj)}(hopsh]hops}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jJhjFubjK)}(hvoid *dd_handleh](jM)}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]jYah"]h$]h&]uh1jLhjubj)}(h h]h }(hj*hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(hjh]h*}(hj8hhhNhNubah}(h]h ]j%ah"]h$]h&]uh1jhjubj)}(h dd_handleh]h dd_handle}(hjEhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jJhjFubeh}(h]h ]h"]h$]h&]hhuh1jDhjhhhjhM#ubeh}(h]h ]h"]h$]h&]hh add_permalinkuh1jsphinx_line_type declaratorhjhhhjhM#ubah}(h]jah ](sig sig-objecteh"]h$]h&] is_multiline _toc_parts) _toc_namehuh1jhjhM#hjhhubh desc_content)}(hhh]h)}(h*register for the firmware upload sysfs APIh]h*register for the firmware upload sysfs API}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1hhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chMhjvhhubah}(h]h ]h"]h$]h&]uh1jthjhhhjhM#ubeh}(h]h ](jfunctioneh"]h$]h&]domainjobjtypejdesctypejnoindex noindexentrynocontentsentryuh1jhhhjhNhNubh container)}(hX5**Parameters** ``struct module *module`` kernel module of this device ``struct device *parent`` parent device instantiating firmware upload ``const char *name`` firmware name to be associated with this device ``const struct fw_upload_ops *ops`` pointer to structure of firmware upload ops ``void *dd_handle`` pointer to parent driver private data **name** must be unique among all users of firmware upload. The firmware sysfs files for this device will be found at /sys/class/firmware/**name**. **Return** struct fw_upload pointer or ERR_PTR()h](h)}(h**Parameters**h]hstrong)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chMhjubhdefinition_list)}(hhh](hdefinition_list_item)}(h7``struct module *module`` kernel module of this device h](hterm)}(h``struct module *module``h]hliteral)}(hjh]hstruct module *module}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chMhjubh definition)}(hhh]h)}(hkernel module of this deviceh]hkernel module of this device}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhjubj)}(hF``struct device *parent`` parent device instantiating firmware upload h](j)}(h``struct device *parent``h]j)}(hjh]hstruct device *parent}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chMhjubj)}(hhh]h)}(h+parent device instantiating firmware uploadh]h+parent device instantiating firmware upload}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhjubj)}(hE``const char *name`` firmware name to be associated with this device h](j)}(h``const char *name``h]j)}(hj@h]hconst char *name}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj>ubah}(h]h ]h"]h$]h&]uh1jhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chMhj:ubj)}(hhh]h)}(h/firmware name to be associated with this deviceh]h/firmware name to be associated with this device}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjUhMhjVubah}(h]h ]h"]h$]h&]uh1jhj:ubeh}(h]h ]h"]h$]h&]uh1jhjUhMhjubj)}(hP``const struct fw_upload_ops *ops`` pointer to structure of firmware upload ops h](j)}(h#``const struct fw_upload_ops *ops``h]j)}(hjyh]hconst struct fw_upload_ops *ops}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjwubah}(h]h ]h"]h$]h&]uh1jhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chMhjsubj)}(hhh]h)}(h+pointer to structure of firmware upload opsh]h+pointer to structure of firmware upload ops}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjsubeh}(h]h ]h"]h$]h&]uh1jhjhMhjubj)}(h``void *dd_handle`` pointer to parent driver private data **name** must be unique among all users of firmware upload. The firmware sysfs files for this device will be found at /sys/class/firmware/**name**. h](j)}(h``void *dd_handle``h]j)}(hjh]hvoid *dd_handle}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chMhjubj)}(hhh](h)}(h%pointer to parent driver private datah]h%pointer to parent driver private data}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chMhjubh)}(h**name** must be unique among all users of firmware upload. The firmware sysfs files for this device will be found at /sys/class/firmware/**name**.h](j)}(h**name**h]hname}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh must be unique among all users of firmware upload. The firmware sysfs files for this device will be found at /sys/class/firmware/}(hjhhhNhNubj)}(h**name**h]hname}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chMhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhjubeh}(h]h ]h"]h$]h&]uh1jhjubh)}(h **Return**h]j)}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chM hjubh)}(h%struct fw_upload pointer or ERR_PTR()h]h%struct fw_upload pointer or ERR_PTR()}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chM hjubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubeh}(h]firmware-upload-registerah ]h"]firmware_upload_registerah$]h&]uh1hhhhhhhhKRubh)}(hhh](h)}(hfirmware_upload_unregisterh]hfirmware_upload_unregister}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhjQhhhhhKWubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j'firmware_upload_unregister (C function)c.firmware_upload_unregisterhNtauh1jhjQhhhNhNubj)}(hhh](j)}(h=void firmware_upload_unregister (struct fw_upload *fw_upload)h]j)}(hhj ubj)}(hhh]h)}(hPRequired: Check for the completion of the HW authentication/programming process.h]hPRequired: Check for the completion of the HW authentication/programming process.}(hj* hhhNhNubah}(h]h ]h"]h$]h&]uh1hhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhK=hj' ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj& hK>hjubj)}(h``cancel`` Required: Request cancellation of update. This op is called from the context of a different kernel thread, so race conditions need to be considered. h](j)}(h ``cancel``h]j)}(hjK h]hcancel}(hjM hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjI ubah}(h]h ]h"]h$]h&]uh1jhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhKAhjE ubj)}(hhh]h)}(hRequired: Request cancellation of update. This op is called from the context of a different kernel thread, so race conditions need to be considered.h]hRequired: Request cancellation of update. This op is called from the context of a different kernel thread, so race conditions need to be considered.}(hjd hhhNhNubah}(h]h ]h"]h$]h&]uh1hhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhK?hja ubah}(h]h ]h"]h$]h&]uh1jhjE ubeh}(h]h ]h"]h$]h&]uh1jhj` hKAhjubj)}(h``cleanup`` Optional: Complements the prepare() function and is called at the completion of the update, on success or failure, if the prepare function succeeded.h](j)}(h ``cleanup``h]j)}(hj h]hcleanup}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhKDhj ubj)}(hhh]h)}(hOptional: Complements the prepare() function and is called at the completion of the update, on success or failure, if the prepare function succeeded.h]hOptional: Complements the prepare() function and is called at the completion of the update, on success or failure, if the prepare function succeeded.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhKBhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hKDhjubeh}(h]h ]h"]h$]h&]uh1jhjMubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubeh}(h]firmware-upload-opsah ]h"]firmware upload opsah$]h&]uh1hhhhhhhhK\ubh)}(hhh](h)}(hFirmware Upload Progress Codesh]hFirmware Upload Progress Codes}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKaubh)}(hThe following progress codes are used internally by the firmware loader. Corresponding strings are reported through the status sysfs node that is described below and are documented in the ABI documentation.h]hThe following progress codes are used internally by the firmware loader. Corresponding strings are reported through the status sysfs node that is described below and are documented in the ABI documentation.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKbhj hhubj)}(hhh]h}(h]h ]h"]h$]h&]entries](jfw_upload_prog (C enum)c.fw_upload_proghNtauh1jhj hhhNhNubj)}(hhh](j)}(hfw_upload_progh]j)}(henum fw_upload_progh](j)}(henumh]henum}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhKubj)}(h h]h }(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhhj hKubj*)}(hfw_upload_progh]j)}(hj h]hfw_upload_prog}(hj' hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj# ubah}(h]h ](j?j@eh"]h$]h&]hhuh1j)hj hhhj hKubeh}(h]h ]h"]h$]h&]hhjfuh1jjgjhhj hhhj hKubah}(h]j ah ](jljmeh"]h$]h&]jqjr)jshuh1jhj hKhj hhubju)}(hhh]h)}(hfirmware upload progress codesh]hfirmware upload progress codes}(hjI hhhNhNubah}(h]h ]h"]h$]h&]uh1hhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhK hjF hhubah}(h]h ]h"]h$]h&]uh1jthj hhhj hKubeh}(h]h ](jenumeh"]h$]h&]jjjja jja jjjuh1jhhhj hNhNubj)}(hX**Constants** ``FW_UPLOAD_PROG_IDLE`` there is no firmware upload in progress ``FW_UPLOAD_PROG_RECEIVING`` worker thread is receiving firmware data ``FW_UPLOAD_PROG_PREPARING`` target device is preparing for firmware upload ``FW_UPLOAD_PROG_TRANSFERRING`` data is being copied to the device ``FW_UPLOAD_PROG_PROGRAMMING`` device is performing the firmware update ``FW_UPLOAD_PROG_MAX`` Maximum progress code markerh](h)}(h **Constants**h]j)}(hjk h]h Constants}(hjm hhhNhNubah}(h]h ]h"]h$]h&]uh1jhji ubah}(h]h ]h"]h$]h&]uh1hhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhKhje ubj)}(hhh](j)}(h@``FW_UPLOAD_PROG_IDLE`` there is no firmware upload in progress h](j)}(h``FW_UPLOAD_PROG_IDLE``h]j)}(hj h]hFW_UPLOAD_PROG_IDLE}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhKhj ubj)}(hhh]h)}(h'there is no firmware upload in progressh]h'there is no firmware upload in progress}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hKhj ubj)}(hF``FW_UPLOAD_PROG_RECEIVING`` worker thread is receiving firmware data h](j)}(h``FW_UPLOAD_PROG_RECEIVING``h]j)}(hj h]hFW_UPLOAD_PROG_RECEIVING}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhKhj ubj)}(hhh]h)}(h(worker thread is receiving firmware datah]h(worker thread is receiving firmware data}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hKhj ubj)}(hL``FW_UPLOAD_PROG_PREPARING`` target device is preparing for firmware upload h](j)}(h``FW_UPLOAD_PROG_PREPARING``h]j)}(hj h]hFW_UPLOAD_PROG_PREPARING}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhKhj ubj)}(hhh]h)}(h.target device is preparing for firmware uploadh]h.target device is preparing for firmware upload}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hKhj ubj)}(hC``FW_UPLOAD_PROG_TRANSFERRING`` data is being copied to the device h](j)}(h``FW_UPLOAD_PROG_TRANSFERRING``h]j)}(hj5 h]hFW_UPLOAD_PROG_TRANSFERRING}(hj7 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj3 ubah}(h]h ]h"]h$]h&]uh1jhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhKhj/ ubj)}(hhh]h)}(h"data is being copied to the deviceh]h"data is being copied to the device}(hjN hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjJ hKhjK ubah}(h]h ]h"]h$]h&]uh1jhj/ ubeh}(h]h ]h"]h$]h&]uh1jhjJ hKhj ubj)}(hH``FW_UPLOAD_PROG_PROGRAMMING`` device is performing the firmware update h](j)}(h``FW_UPLOAD_PROG_PROGRAMMING``h]j)}(hjn h]hFW_UPLOAD_PROG_PROGRAMMING}(hjp hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjl ubah}(h]h ]h"]h$]h&]uh1jhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhKhjh ubj)}(hhh]h)}(h(device is performing the firmware updateh]h(device is performing the firmware update}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKhj ubah}(h]h ]h"]h$]h&]uh1jhjh ubeh}(h]h ]h"]h$]h&]uh1jhj hKhj ubj)}(h3``FW_UPLOAD_PROG_MAX`` Maximum progress code markerh](j)}(h``FW_UPLOAD_PROG_MAX``h]j)}(hj h]hFW_UPLOAD_PROG_MAX}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhKhj ubj)}(hhh]h)}(hMaximum progress code markerh]hMaximum progress code marker}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhK hj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hKhj ubeh}(h]h ]h"]h$]h&]uh1jhje ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhj hhhNhNubeh}(h]firmware-upload-progress-codesah ]h"]firmware upload progress codesah$]h&]uh1hhhhhhhhKaubh)}(hhh](h)}(hFirmware Upload Error Codesh]hFirmware Upload Error Codes}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKjubh)}(hOThe following error codes may be returned by the driver ops in case of failure:h]hOThe following error codes may be returned by the driver ops in case of failure:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKkhj hhubj)}(hhh]h}(h]h ]h"]h$]h&]entries](jfw_upload_err (C enum)c.fw_upload_errhNtauh1jhj hhhNhNubj)}(hhh](j)}(h fw_upload_errh]j)}(henum fw_upload_errh](j)}(hj h]henum}(hj( hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj$ hhhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhKubj)}(h h]h }(hj6 hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj$ hhhj5 hKubj*)}(h fw_upload_errh]j)}(hj" h]h fw_upload_err}(hjH hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjD ubah}(h]h ](j?j@eh"]h$]h&]hhuh1j)hj$ hhhj5 hKubeh}(h]h ]h"]h$]h&]hhjfuh1jjgjhhj hhhj5 hKubah}(h]j ah ](jljmeh"]h$]h&]jqjr)jshuh1jhj5 hKhj hhubju)}(hhh]h)}(hfirmware upload error codesh]hfirmware upload error codes}(hjj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhKhjg hhubah}(h]h ]h"]h$]h&]uh1jthj hhhj5 hKubeh}(h]h ](jenumeh"]h$]h&]jjjj jj jjjuh1jhhhj hNhNubj)}(hX**Constants** ``FW_UPLOAD_ERR_NONE`` returned to indicate success ``FW_UPLOAD_ERR_HW_ERROR`` error signalled by hardware, see kernel log ``FW_UPLOAD_ERR_TIMEOUT`` SW timed out on handshake with HW/firmware ``FW_UPLOAD_ERR_CANCELED`` upload was cancelled by the user ``FW_UPLOAD_ERR_BUSY`` there is an upload operation already in progress ``FW_UPLOAD_ERR_INVALID_SIZE`` invalid firmware image size ``FW_UPLOAD_ERR_RW_ERROR`` read or write to HW failed, see kernel log ``FW_UPLOAD_ERR_WEAROUT`` FLASH device is approaching wear-out, wait & retry ``FW_UPLOAD_ERR_FW_INVALID`` invalid firmware file ``FW_UPLOAD_ERR_MAX`` Maximum error code markerh](h)}(h **Constants**h]j)}(hj h]h Constants}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1hhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhKhj ubj)}(hhh](j)}(h4``FW_UPLOAD_ERR_NONE`` returned to indicate success h](j)}(h``FW_UPLOAD_ERR_NONE``h]j)}(hj h]hFW_UPLOAD_ERR_NONE}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhKhj ubj)}(hhh]h)}(hreturned to indicate successh]hreturned to indicate success}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hKhj ubj)}(hG``FW_UPLOAD_ERR_HW_ERROR`` error signalled by hardware, see kernel log h](j)}(h``FW_UPLOAD_ERR_HW_ERROR``h]j)}(hj h]hFW_UPLOAD_ERR_HW_ERROR}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK hj ubj)}(hhh]h)}(h+error signalled by hardware, see kernel logh]h+error signalled by hardware, see kernel log}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hK hj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hK hj ubj)}(hE``FW_UPLOAD_ERR_TIMEOUT`` SW timed out on handshake with HW/firmware h](j)}(h``FW_UPLOAD_ERR_TIMEOUT``h]j)}(hj h]hFW_UPLOAD_ERR_TIMEOUT}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK#hj ubj)}(hhh]h)}(h*SW timed out on handshake with HW/firmwareh]h*SW timed out on handshake with HW/firmware}(hj6 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj2 hK#hj3 ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj2 hK#hj ubj)}(h<``FW_UPLOAD_ERR_CANCELED`` upload was cancelled by the user h](j)}(h``FW_UPLOAD_ERR_CANCELED``h]j)}(hjV h]hFW_UPLOAD_ERR_CANCELED}(hjX hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjT ubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK&hjP ubj)}(hhh]h)}(h upload was cancelled by the userh]h upload was cancelled by the user}(hjo hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjk hK&hjl ubah}(h]h ]h"]h$]h&]uh1jhjP ubeh}(h]h ]h"]h$]h&]uh1jhjk hK&hj ubj)}(hH``FW_UPLOAD_ERR_BUSY`` there is an upload operation already in progress h](j)}(h``FW_UPLOAD_ERR_BUSY``h]j)}(hj h]hFW_UPLOAD_ERR_BUSY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK)hj ubj)}(hhh]h)}(h0there is an upload operation already in progressh]h0there is an upload operation already in progress}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hK)hj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hK)hj ubj)}(h;``FW_UPLOAD_ERR_INVALID_SIZE`` invalid firmware image size h](j)}(h``FW_UPLOAD_ERR_INVALID_SIZE``h]j)}(hj h]hFW_UPLOAD_ERR_INVALID_SIZE}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK,hj ubj)}(hhh]h)}(hinvalid firmware image sizeh]hinvalid firmware image size}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hK,hj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hK,hj ubj)}(hF``FW_UPLOAD_ERR_RW_ERROR`` read or write to HW failed, see kernel log h](j)}(h``FW_UPLOAD_ERR_RW_ERROR``h]j)}(hjh]hFW_UPLOAD_ERR_RW_ERROR}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK/hj ubj)}(hhh]h)}(h*read or write to HW failed, see kernel logh]h*read or write to HW failed, see kernel log}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK/hjubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhjhK/hj ubj)}(hM``FW_UPLOAD_ERR_WEAROUT`` FLASH device is approaching wear-out, wait & retry h](j)}(h``FW_UPLOAD_ERR_WEAROUT``h]j)}(hj:h]hFW_UPLOAD_ERR_WEAROUT}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj8ubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK2hj4ubj)}(hhh]h)}(h2FLASH device is approaching wear-out, wait & retryh]h2FLASH device is approaching wear-out, wait & retry}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhjOhK2hjPubah}(h]h ]h"]h$]h&]uh1jhj4ubeh}(h]h ]h"]h$]h&]uh1jhjOhK2hj ubj)}(h3``FW_UPLOAD_ERR_FW_INVALID`` invalid firmware file h](j)}(h``FW_UPLOAD_ERR_FW_INVALID``h]j)}(hjsh]hFW_UPLOAD_ERR_FW_INVALID}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjqubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK5hjmubj)}(hhh]h)}(hinvalid firmware fileh]hinvalid firmware file}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK5hjubah}(h]h ]h"]h$]h&]uh1jhjmubeh}(h]h ]h"]h$]h&]uh1jhjhK5hj ubj)}(h/``FW_UPLOAD_ERR_MAX`` Maximum error code markerh](j)}(h``FW_UPLOAD_ERR_MAX``h]j)}(hjh]hFW_UPLOAD_ERR_MAX}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK7hjubj)}(hhh]h)}(hMaximum error code markerh]hMaximum error code marker}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK8hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhK7hj ubeh}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhj hhhNhNubeh}(h]firmware-upload-error-codesah ]h"]firmware upload error codesah$]h&]uh1hhhhhhhhKjubeh}(h]register-for-firmware-uploadah ]h"]register for firmware uploadah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hSysfs Attributesh]hSysfs Attributes}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKrubh)}(hXDIn addition to the *loading* and *data* sysfs files, there are additional sysfs files to monitor the status of the data transfer to the target device and to determine the final pass/fail status of the transfer. Depending on the device and the size of the firmware image, a firmware update could take milliseconds or minutes.h](hIn addition to the }(hjhhhNhNubh)}(h *loading*h]hloading}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(hjhhhNhNubh)}(h*data*h]hdata}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhX sysfs files, there are additional sysfs files to monitor the status of the data transfer to the target device and to determine the final pass/fail status of the transfer. Depending on the device and the size of the firmware image, a firmware update could take milliseconds or minutes.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKthjhhubh)}(hThe additional sysfs files are:h]hThe additional sysfs files are:}(hj@hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKzhjhhubh bullet_list)}(hhh](h list_item)}(hDstatus - provides an indication of the progress of a firmware updateh]h)}(hjWh]hDstatus - provides an indication of the progress of a firmware update}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK|hjUubah}(h]h ]h"]h$]h&]uh1jShjPhhhhhNubjT)}(h?error - provides error information for a failed firmware updateh]h)}(hjnh]h?error - provides error information for a failed firmware update}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK}hjlubah}(h]h ]h"]h$]h&]uh1jShjPhhhhhNubjT)}(h>remaining_size - tracks the data transfer portion of an updateh]h)}(hjh]h>remaining_size - tracks the data transfer portion of an update}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK~hjubah}(h]h ]h"]h$]h&]uh1jShjPhhhhhNubjT)}(h1cancel - echo 1 to this file to cancel the updateh]h)}(hjh]h1cancel - echo 1 to this file to cancel the update}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jShjPhhhhhNubeh}(h]h ]h"]h$]h&]bulletjuh1jNhhhK|hjhhubeh}(h]sysfs-attributesah ]h"]sysfs attributesah$]h&]uh1hhhhhhhhKrubeh}(h]firmware-upload-apiah ]h"]firmware upload apiah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jjjjjNjKjjj j j j jjjju nametypes}(jjjNjj j jjuh}(jhjhjKjjjjjQjnjsj jjjj j j j jj j j jju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.