1 .. SPDX-License-Identifier: GPL-2.0 1 .. SPDX-License-Identifier: GPL-2.0 2 2 3 =================== 3 =================== 4 Firmware Upload API 4 Firmware Upload API 5 =================== 5 =================== 6 6 7 A device driver that registers with the firmwa 7 A device driver that registers with the firmware loader will expose 8 persistent sysfs nodes to enable users to init 8 persistent sysfs nodes to enable users to initiate firmware updates for 9 that device. It is the responsibility of the 9 that device. It is the responsibility of the device driver and/or the 10 device itself to perform any validation on the 10 device itself to perform any validation on the data received. Firmware 11 upload uses the same *loading* and *data* sysf 11 upload uses the same *loading* and *data* sysfs files described in the 12 documentation for firmware fallback. It also a 12 documentation for firmware fallback. It also adds additional sysfs files 13 to provide status on the transfer of the firmw 13 to provide status on the transfer of the firmware image to the device. 14 14 15 Register for firmware upload 15 Register for firmware upload 16 ============================ 16 ============================ 17 17 18 A device driver registers for firmware upload 18 A device driver registers for firmware upload by calling 19 firmware_upload_register(). Among the paramete 19 firmware_upload_register(). Among the parameter list is a name to 20 identify the device under /sys/class/firmware. 20 identify the device under /sys/class/firmware. A user may initiate a 21 firmware upload by echoing a 1 to the *loading 21 firmware upload by echoing a 1 to the *loading* sysfs file for the target 22 device. Next, the user writes the firmware ima 22 device. Next, the user writes the firmware image to the *data* sysfs 23 file. After writing the firmware data, the use 23 file. After writing the firmware data, the user echos 0 to the *loading* 24 sysfs file to signal completion. Echoing 0 to 24 sysfs file to signal completion. Echoing 0 to *loading* also triggers the 25 transfer of the firmware to the lower-lever de 25 transfer of the firmware to the lower-lever device driver in the context 26 of a kernel worker thread. 26 of a kernel worker thread. 27 27 28 To use the firmware upload API, write a driver 28 To use the firmware upload API, write a driver that implements a set of 29 ops. The probe function calls firmware_upload 29 ops. The probe function calls firmware_upload_register() and the remove 30 function calls firmware_upload_unregister() su 30 function calls firmware_upload_unregister() such as:: 31 31 32 static const struct fw_upload_ops m10b 32 static const struct fw_upload_ops m10bmc_ops = { 33 .prepare = m10bmc_sec_prepare, 33 .prepare = m10bmc_sec_prepare, 34 .write = m10bmc_sec_write, 34 .write = m10bmc_sec_write, 35 .poll_complete = m10bmc_sec_po 35 .poll_complete = m10bmc_sec_poll_complete, 36 .cancel = m10bmc_sec_cancel, 36 .cancel = m10bmc_sec_cancel, 37 .cleanup = m10bmc_sec_cleanup, 37 .cleanup = m10bmc_sec_cleanup, 38 }; 38 }; 39 39 40 static int m10bmc_sec_probe(struct pla 40 static int m10bmc_sec_probe(struct platform_device *pdev) 41 { 41 { 42 const char *fw_name, *truncate 42 const char *fw_name, *truncate; 43 struct m10bmc_sec *sec; 43 struct m10bmc_sec *sec; 44 struct fw_upload *fwl; 44 struct fw_upload *fwl; 45 unsigned int len; 45 unsigned int len; 46 46 47 sec = devm_kzalloc(&pdev->dev, 47 sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL); 48 if (!sec) 48 if (!sec) 49 return -ENOMEM; 49 return -ENOMEM; 50 50 51 sec->dev = &pdev->dev; 51 sec->dev = &pdev->dev; 52 sec->m10bmc = dev_get_drvdata( 52 sec->m10bmc = dev_get_drvdata(pdev->dev.parent); 53 dev_set_drvdata(&pdev->dev, se 53 dev_set_drvdata(&pdev->dev, sec); 54 54 55 fw_name = dev_name(sec->dev); 55 fw_name = dev_name(sec->dev); 56 truncate = strstr(fw_name, ".a 56 truncate = strstr(fw_name, ".auto"); 57 len = (truncate) ? truncate - 57 len = (truncate) ? truncate - fw_name : strlen(fw_name); 58 sec->fw_name = kmemdup_nul(fw_ 58 sec->fw_name = kmemdup_nul(fw_name, len, GFP_KERNEL); 59 59 60 fwl = firmware_upload_register 60 fwl = firmware_upload_register(THIS_MODULE, sec->dev, sec->fw_name, 61 61 &m10bmc_ops, sec); 62 if (IS_ERR(fwl)) { 62 if (IS_ERR(fwl)) { 63 dev_err(sec->dev, "Fir 63 dev_err(sec->dev, "Firmware Upload driver failed to start\n"); 64 kfree(sec->fw_name); 64 kfree(sec->fw_name); 65 return PTR_ERR(fwl); 65 return PTR_ERR(fwl); 66 } 66 } 67 67 68 sec->fwl = fwl; 68 sec->fwl = fwl; 69 return 0; 69 return 0; 70 } 70 } 71 71 72 static int m10bmc_sec_remove(struct pl 72 static int m10bmc_sec_remove(struct platform_device *pdev) 73 { 73 { 74 struct m10bmc_sec *sec = dev_g 74 struct m10bmc_sec *sec = dev_get_drvdata(&pdev->dev); 75 75 76 firmware_upload_unregister(sec 76 firmware_upload_unregister(sec->fwl); 77 kfree(sec->fw_name); 77 kfree(sec->fw_name); 78 return 0; 78 return 0; 79 } 79 } 80 80 81 firmware_upload_register 81 firmware_upload_register 82 ------------------------ 82 ------------------------ 83 .. kernel-doc:: drivers/base/firmware_loader/s 83 .. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c 84 :identifiers: firmware_upload_register 84 :identifiers: firmware_upload_register 85 85 86 firmware_upload_unregister 86 firmware_upload_unregister 87 -------------------------- 87 -------------------------- 88 .. kernel-doc:: drivers/base/firmware_loader/s 88 .. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c 89 :identifiers: firmware_upload_unregister 89 :identifiers: firmware_upload_unregister 90 90 91 Firmware Upload Ops 91 Firmware Upload Ops 92 ------------------- 92 ------------------- 93 .. kernel-doc:: include/linux/firmware.h 93 .. kernel-doc:: include/linux/firmware.h 94 :identifiers: fw_upload_ops 94 :identifiers: fw_upload_ops 95 95 96 Firmware Upload Progress Codes 96 Firmware Upload Progress Codes 97 ------------------------------ 97 ------------------------------ 98 The following progress codes are used internal 98 The following progress codes are used internally by the firmware loader. 99 Corresponding strings are reported through the 99 Corresponding strings are reported through the status sysfs node that 100 is described below and are documented in the A 100 is described below and are documented in the ABI documentation. 101 101 102 .. kernel-doc:: drivers/base/firmware_loader/s 102 .. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.h 103 :identifiers: fw_upload_prog 103 :identifiers: fw_upload_prog 104 104 105 Firmware Upload Error Codes 105 Firmware Upload Error Codes 106 --------------------------- 106 --------------------------- 107 The following error codes may be returned by t 107 The following error codes may be returned by the driver ops in case of 108 failure: 108 failure: 109 109 110 .. kernel-doc:: include/linux/firmware.h 110 .. kernel-doc:: include/linux/firmware.h 111 :identifiers: fw_upload_err 111 :identifiers: fw_upload_err 112 112 113 Sysfs Attributes 113 Sysfs Attributes 114 ================ 114 ================ 115 115 116 In addition to the *loading* and *data* sysfs 116 In addition to the *loading* and *data* sysfs files, there are additional 117 sysfs files to monitor the status of the data 117 sysfs files to monitor the status of the data transfer to the target 118 device and to determine the final pass/fail st 118 device and to determine the final pass/fail status of the transfer. 119 Depending on the device and the size of the fi 119 Depending on the device and the size of the firmware image, a firmware 120 update could take milliseconds or minutes. 120 update could take milliseconds or minutes. 121 121 122 The additional sysfs files are: 122 The additional sysfs files are: 123 123 124 * status - provides an indication of the progr 124 * status - provides an indication of the progress of a firmware update 125 * error - provides error information for a fai 125 * error - provides error information for a failed firmware update 126 * remaining_size - tracks the data transfer po 126 * remaining_size - tracks the data transfer portion of an update 127 * cancel - echo 1 to this file to cancel the u 127 * cancel - echo 1 to this file to cancel the update
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.