Esphinx.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]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget1/translations/pt_BR/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&]uh1hhjhhhhhKubh)}(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 }(hj$hhhNhNubh)}(h *loading*h]hloading}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj$ubhS sysfs file for the target device. Next, the user writes the firmware image to the }(hj$hhhNhNubh)}(h*data*h]hdata}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj$ubhF sysfs file. After writing the firmware data, the user echos 0 to the }(hj$hhhNhNubh)}(h *loading*h]hloading}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj$ubh/ sysfs file to signal completion. Echoing 0 to }(hj$hhhNhNubh)}(h *loading*h]hloading}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj$ubhv also triggers the transfer of the firmware to the lower-lever device driver in the context of a kernel worker thread.}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(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:}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh 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; }}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhK hjhhubh)}(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.chMubhdesc_sig_space)}(h h]h }(hjhhhNhNubah}(h]h ]wah"]h$]h&]uh1jhjhhhjhMubh)}(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)}j firmware_upload_registersbc.firmware_upload_registerasbuh1hhjhhhjhMubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhhjhMubhdesc_sig_punctuation)}(h*h]h*}(hj.hhhNhNubah}(h]h ]pah"]h$]h&]uh1j,hjhhhjhMubh desc_name)}(hfirmware_upload_registerh]j)}(hjh]hfirmware_upload_register}(hjChhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj?ubah}(h]h ](sig-namedescnameeh"]h$]h&]hhuh1j=hjhhhjhMubhdesc_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}(hjdhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj`ubj)}(h h]h }(hjqhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj`ubh)}(hhh]j)}(hmoduleh]hmodule}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&] refdomainj reftypej  reftargetjmodnameN classnameNjj)}j]jc.firmware_upload_registerasbuh1hhj`ubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj`ubj-)}(hj0h]h*}(hjhhhNhNubah}(h]h ]j9ah"]h$]h&]uh1j,hj`ubj)}(hmoduleh]hmodule}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj`ubeh}(h]h ]h"]h$]h&]noemphhhuh1j^hjZubj_)}(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&] refdomainj reftypej  reftargetjmodnameN classnameNjj)}j]jc.firmware_upload_registerasbuh1hhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj-)}(hj0h]h*}(hjhhhNhNubah}(h]h ]j9ah"]h$]h&]uh1j,hjubj)}(hparenth]hparent}(hj+hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1j^hjZubj_)}(hconst char *nameh](j)}(hconsth]hconst}(hjDhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj@ubj)}(h h]h }(hjRhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj@ubhdesc_sig_keyword_type)}(hcharh]hchar}(hjbhhhNhNubah}(h]h ]ktah"]h$]h&]uh1j`hj@ubj)}(h h]h }(hjqhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj@ubj-)}(hj0h]h*}(hjhhhNhNubah}(h]h ]j9ah"]h$]h&]uh1j,hj@ubj)}(hnameh]hname}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj@ubeh}(h]h ]h"]h$]h&]noemphhhuh1j^hjZubj_)}(hconst struct fw_upload_ops *opsh](j)}(hjFh]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&] refdomainj reftypej  reftargetjmodnameN classnameNjj)}j]jc.firmware_upload_registerasbuh1hhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj-)}(hj0h]h*}(hj hhhNhNubah}(h]h ]j9ah"]h$]h&]uh1j,hjubj)}(hopsh]hops}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1j^hjZubj_)}(hvoid *dd_handleh](ja)}(hvoidh]hvoid}(hj0hhhNhNubah}(h]h ]jmah"]h$]h&]uh1j`hj,ubj)}(h h]h }(hj>hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj,ubj-)}(hj0h]h*}(hjLhhhNhNubah}(h]h ]j9ah"]h$]h&]uh1j,hj,ubj)}(h dd_handleh]h dd_handle}(hjYhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj,ubeh}(h]h ]h"]h$]h&]noemphhhuh1j^hjZubeh}(h]h ]h"]h$]h&]hhuh1jXhjhhhjhMubeh}(h]h ]h"]h$]h&]hhƌ add_permalinkuh1jsphinx_line_type declaratorhjhhhjhMubah}(h]jah ](sig sig-objecteh"]h$]h&] is_multiline _toc_parts) _toc_namehuh1jhjhMhjhhubh desc_content)}(hhh]h)}(h*register for the firmware upload sysfs APIh]h*register for the firmware upload sysfs API}(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.chMhjhhubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubeh}(h]h ](j functioneh"]h$]h&]domainj objtypejdesctypejnoindex noindexentrynocontentsentryuh1jhhhjhNhNubh container)}(hXL**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 **Description** **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}(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+parent device instantiating firmware uploadh]h+parent device instantiating firmware upload}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj0hMhj1ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj0hMhjubj)}(hE``const char *name`` firmware name to be associated with this device h](j)}(h``const char *name``h]j)}(hjTh]hconst char *name}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjRubah}(h]h ]h"]h$]h&]uh1jhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:83: ./drivers/base/firmware_loader/sysfs_upload.chMhjNubj)}(hhh]h)}(h/firmware name to be associated with this deviceh]h/firmware name to be associated with this device}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjihMhjjubah}(h]h ]h"]h$]h&]uh1jhjNubeh}(h]h ]h"]h$]h&]uh1jhjihMhjubj)}(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)}(hjh]hconst struct fw_upload_ops *ops}(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 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&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhjubj)}(h:``void *dd_handle`` pointer to parent driver private data 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&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhjubeh}(h]h ]h"]h$]h&]uh1jhjubh)}(h**Description**h]j)}(hjh]h Description}(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.chMhjubh block_quote)}(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]h)}(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}(hj!hhhNhNubah}(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}(hj3hhhNhNubah}(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.chMhjubah}(h]h ]h"]h$]h&]uh1jhjKhMhjubh)}(h **Return**h]j)}(hjTh]hReturn}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjRubah}(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()}(hjjhhhNhNubah}(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&]uh1hhjhhhhhKRubh)}(hhh](h)}(hfirmware_upload_unregisterh]hfirmware_upload_unregister}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKWubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j'firmware_upload_unregister (C function)c.firmware_upload_unregisterhNtauh1jhjhhhNhNubj)}(hhh](j)}(h=void firmware_upload_unregister (struct fw_upload *fw_upload)h]j)}(h)}(hfirmware_upload_unregisterh]j)}(hfirmware_upload_unregisterh]hfirmware_upload_unregister}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubah}(h]h ](jSjTeh"]h$]h&]hhuh1j=hjhhhjhMubjY)}(h(struct fw_upload *fw_upload)h]j_)}(hstruct fw_upload *fw_uploadh](j)}(hjh]hstruct}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj)}(h h]h }(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubh)}(hhh]j)}(h fw_uploadh]h fw_upload}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&] refdomainj reftypej  reftargetjmodnameN classnameNjj)}j]j)}j jsbc.firmware_upload_unregisterasbuh1hhjubj)}(h h]h }(hj-hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubj-)}(hj0h]h*}(hj;hhhNhNubah}(h]h ]j9ah"]h$]h&]uh1j,hjubj)}(h fw_uploadh]h fw_upload}(hjHhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]noemphhhuh1j^hjubah}(h]h ]h"]h$]h&]hhuh1jXhjhhhjhMubeh}(h]h ]h"]h$]h&]hhjzuh1jj{j|hjhhhjhMubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1jhjhMhjhhubj)}(hhh]h)}(h$Unregister firmware upload interfaceh]h$Unregister firmware upload interface}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:88: ./drivers/base/firmware_loader/sysfs_upload.chMhjohhubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubeh}(h]h ](j functioneh"]h$]h&]jj jjjjjjjuh1jhhhjhNhNubj)}(hM**Parameters** ``struct fw_upload *fw_upload`` pointer to struct fw_uploadh](h)}(h**Parameters**h]j)}(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:88: ./drivers/base/firmware_loader/sysfs_upload.chMhjubj)}(hhh]j)}(h;``struct fw_upload *fw_upload`` pointer to struct fw_uploadh](j)}(h``struct fw_upload *fw_upload``h]j)}(hjh]hstruct fw_upload *fw_upload}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:88: ./drivers/base/firmware_loader/sysfs_upload.chMhjubj)}(hhh]h)}(hpointer to struct fw_uploadh]hpointer to struct fw_upload}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhy/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:88: ./drivers/base/firmware_loader/sysfs_upload.chMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubeh}(h]firmware-upload-unregisterah ]h"]firmware_upload_unregisterah$]h&]uh1hhjhhhhhKWubh)}(hhh](h)}(hFirmware Upload Opsh]hFirmware Upload Ops}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK\ubj)}(hhh]h}(h]h ]h"]h$]h&]entries](jfw_upload_ops (C struct)c.fw_upload_opshNtauh1jhjhhhNhNubj)}(hhh](j)}(h fw_upload_opsh]j)}(hstruct fw_upload_opsh](j)}(hjh]hstruct}(hj&hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj"hhhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhKubj)}(h h]h }(hj4hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj"hhhj3hKubj>)}(h fw_upload_opsh]j)}(hj h]h fw_upload_ops}(hjFhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjBubah}(h]h ](jSjTeh"]h$]h&]hhuh1j=hj"hhhj3hKubeh}(h]h ]h"]h$]h&]hhjzuh1jj{j|hjhhhj3hKubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1jhj3hKhjhhubj)}(hhh]h)}(h5device specific operations to support firmware uploadh]h5device specific operations to support firmware upload}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhK5hjehhubah}(h]h ]h"]h$]h&]uh1jhjhhhj3hKubeh}(h]h ](j structeh"]h$]h&]jj jjjjjjjuh1jhhhjhNhNubj)}(hX**Definition**:: struct fw_upload_ops { enum fw_upload_err (*prepare)(struct fw_upload *fw_upload, const u8 *data, u32 size); enum fw_upload_err (*write)(struct fw_upload *fw_upload, const u8 *data, u32 offset, u32 size, u32 *written); enum fw_upload_err (*poll_complete)(struct fw_upload *fw_upload); void (*cancel)(struct fw_upload *fw_upload); void (*cleanup)(struct fw_upload *fw_upload); }; **Members** ``prepare`` Required: Prepare secure update ``write`` Required: The write() op receives the remaining size to be written and must return the actual size written or a negative error code. The write() op will be called repeatedly until all data is written. ``poll_complete`` Required: Check for the completion of the HW authentication/programming process. ``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. ``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](h)}(h**Definition**::h](j)}(h**Definition**h]h Definition}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhK9hjubj)}(hXstruct fw_upload_ops { enum fw_upload_err (*prepare)(struct fw_upload *fw_upload, const u8 *data, u32 size); enum fw_upload_err (*write)(struct fw_upload *fw_upload, const u8 *data, u32 offset, u32 size, u32 *written); enum fw_upload_err (*poll_complete)(struct fw_upload *fw_upload); void (*cancel)(struct fw_upload *fw_upload); void (*cleanup)(struct fw_upload *fw_upload); };h]hXstruct fw_upload_ops { enum fw_upload_err (*prepare)(struct fw_upload *fw_upload, const u8 *data, u32 size); enum fw_upload_err (*write)(struct fw_upload *fw_upload, const u8 *data, u32 offset, u32 size, u32 *written); enum fw_upload_err (*poll_complete)(struct fw_upload *fw_upload); void (*cancel)(struct fw_upload *fw_upload); void (*cleanup)(struct fw_upload *fw_upload); };}hjsbah}(h]h ]h"]h$]h&]hhuh1jhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhK;hjubh)}(h **Members**h]j)}(hjh]hMembers}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhKChjubj)}(hhh](j)}(h,``prepare`` Required: Prepare secure update h](j)}(h ``prepare``h]j)}(hjh]hprepare}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhf/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:93: ./include/linux/firmware.hhK7hjubj)}(hhh]h)}(hRequired: Prepare secure updateh]hRequired: Prepare secure update}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK7hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhK7hjubj)}(h``write`` Required: The write() op receives the remaining size to be written and must return the actual size written or a negative error code. The write() op will be called repeatedly until all data is written. h](j)}(h ``write``h]j)}(hj h]hwrite}(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.hhKhjB 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.}(hja 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&]uh1jhjB 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)}(hj h]hcancel}(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.hhKAhj| 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.}(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 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&]uh1jhjubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubeh}(h]firmware-upload-opsah ]h"]firmware upload opsah$]h&]uh1hhjhhhhhK\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&]uh1jhj9 hhhz/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:102: ./drivers/base/firmware_loader/sysfs_upload.hhKubj)}(h h]h }(hjL hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj9 hhhjK hKubj>)}(hfw_upload_progh]j)}(hj7 h]hfw_upload_prog}(hj^ hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjZ ubah}(h]h ](jSjTeh"]h$]h&]hhuh1j=hj9 hhhjK hKubeh}(h]h ]h"]h$]h&]hhjzuh1jj{j|hj5 hhhjK hKubah}(h]j0 ah ](jjeh"]h$]h&]jj)jhuh1jhjK hKhj2 hhubj)}(hhh]h)}(hfirmware upload progress codesh]hfirmware upload progress codes}(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} hhubah}(h]h ]h"]h$]h&]uh1jhj2 hhhjK hKubeh}(h]h ](j enumeh"]h$]h&]jj jj jj 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)}(hj h]h Constants}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj 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.hhKhj 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)}(hj3 h]hFW_UPLOAD_PROG_PREPARING}(hj5 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj1 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}(hjL hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjH hKhjI ubah}(h]h ]h"]h$]h&]uh1jhj- ubeh}(h]h ]h"]h$]h&]uh1jhjH hKhj ubj)}(hC``FW_UPLOAD_PROG_TRANSFERRING`` data is being copied to the device h](j)}(h``FW_UPLOAD_PROG_TRANSFERRING``h]j)}(hjl h]hFW_UPLOAD_PROG_TRANSFERRING}(hjn hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjj 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.hhKhjf ubj)}(hhh]h)}(h"data is being copied to the deviceh]h"data is being copied to the device}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKhj ubah}(h]h ]h"]h$]h&]uh1jhjf ubeh}(h]h ]h"]h$]h&]uh1jhj hKhj ubj)}(hH``FW_UPLOAD_PROG_PROGRAMMING`` device is performing the firmware update h](j)}(h``FW_UPLOAD_PROG_PROGRAMMING``h]j)}(hj h]hFW_UPLOAD_PROG_PROGRAMMING}(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(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&]uh1jhj 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&]uh1jhj ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhj hhhNhNubeh}(h]firmware-upload-progress-codesah ]h"]firmware upload progress codesah$]h&]uh1hhjhhhhhKaubh)}(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:}(hj8 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 }(hjm hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj[ hhhjl hKubj>)}(h fw_upload_errh]j)}(hjY h]h fw_upload_err}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj{ ubah}(h]h ](jSjTeh"]h$]h&]hhuh1j=hj[ hhhjl hKubeh}(h]h ]h"]h$]h&]hhjzuh1jj{j|hjW hhhjl hKubah}(h]jR ah ](jjeh"]h$]h&]jj)jhuh1jhjl hKhjT hhubj)}(hhh]h)}(hfirmware upload error codesh]hfirmware upload error codes}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhKhj hhubah}(h]h ]h"]h$]h&]uh1jhjT hhhjl hKubeh}(h]h ](j enumeh"]h$]h&]jj jj 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}(hj4 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj0 hK hj1 ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj0 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)}(hjT h]hFW_UPLOAD_ERR_TIMEOUT}(hjV hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjR ubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK#hjN ubj)}(hhh]h)}(h*SW timed out on handshake with HW/firmwareh]h*SW timed out on handshake with HW/firmware}(hjm hhhNhNubah}(h]h ]h"]h$]h&]uh1hhji hK#hjj ubah}(h]h ]h"]h$]h&]uh1jhjN ubeh}(h]h ]h"]h$]h&]uh1jhji hK#hj ubj)}(h<``FW_UPLOAD_ERR_CANCELED`` upload was cancelled by the user h](j)}(h``FW_UPLOAD_ERR_CANCELED``h]j)}(hj h]hFW_UPLOAD_ERR_CANCELED}(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 upload was cancelled by the userh]h upload was cancelled by the user}(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)}(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}(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)}(hinvalid firmware image sizeh]hinvalid firmware image size}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK,hjubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhjhK,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)}(hj8h]hFW_UPLOAD_ERR_RW_ERROR}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj6ubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK/hj2ubj)}(hhh]h)}(h*read or write to HW failed, see kernel logh]h*read or write to HW failed, see kernel log}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjMhK/hjNubah}(h]h ]h"]h$]h&]uh1jhj2ubeh}(h]h ]h"]h$]h&]uh1jhjMhK/hj ubj)}(hM``FW_UPLOAD_ERR_WEAROUT`` FLASH device is approaching wear-out, wait & retry h](j)}(h``FW_UPLOAD_ERR_WEAROUT``h]j)}(hjqh]hFW_UPLOAD_ERR_WEAROUT}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jhjoubah}(h]h ]h"]h$]h&]uh1jhg/var/lib/git/docbuild/linux/Documentation/driver-api/firmware/fw_upload:110: ./include/linux/firmware.hhK2hjkubj)}(hhh]h)}(h2FLASH device is approaching wear-out, wait & retryh]h2FLASH device is approaching wear-out, wait & retry}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK2hjubah}(h]h ]h"]h$]h&]uh1jhjkubeh}(h]h ]h"]h$]h&]uh1jhjhK2hj ubj)}(h3``FW_UPLOAD_ERR_FW_INVALID`` invalid firmware file h](j)}(h``FW_UPLOAD_ERR_FW_INVALID``h]j)}(hjh]hFW_UPLOAD_ERR_FW_INVALID}(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.hhK5hjubj)}(hhh]h)}(hinvalid firmware fileh]hinvalid firmware file}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK5hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(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&]uh1hhjhhhhhKjubeh}(h]register-for-firmware-uploadah ]h"]register for firmware uploadah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hSysfs Attributesh]hSysfs Attributes}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj4hhhhhKrubh)}(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 }(hjEhhhNhNubh)}(h *loading*h]hloading}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjEubh and }(hjEhhhNhNubh)}(h*data*h]hdata}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjEubhX 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.}(hjEhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKthj4hhubh)}(hThe additional sysfs files are:h]hThe additional sysfs files are:}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKzhj4hhubh bullet_list)}(hhh](h list_item)}(hDstatus - provides an indication of the progress of a firmware updateh]h)}(hjh]hDstatus - provides an indication of the progress of a firmware update}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK|hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h?error - provides error information for a failed firmware updateh]h)}(hjh]h?error - provides error information for a failed firmware update}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK}hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(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&]uh1jhjhhhhhNubj)}(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&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]bulletj0uh1jhhhK|hj4hhubeh}(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_handlerj"error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcehnj _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}(jjj1j.jjjjj j j$ j! j)j&jju nametypes}(jj1jjj j$ j)juh}(jhj.jjjjjjjjjj jjjj! j j0 j5 j&j' jR jW jj4u 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.