Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 
0003 ===================
0004 Firmware Upload API
0005 ===================
0006 
0007 A device driver that registers with the firmware loader will expose
0008 persistent sysfs nodes to enable users to initiate firmware updates for
0009 that device.  It is the responsibility of the device driver and/or the
0010 device itself to perform any validation on the data received. Firmware
0011 upload uses the same *loading* and *data* sysfs files described in the
0012 documentation for firmware fallback. It also adds additional sysfs files
0013 to provide status on the transfer of the firmware image to the device.
0014 
0015 Register for firmware upload
0016 ============================
0017 
0018 A device driver registers for firmware upload by calling
0019 firmware_upload_register(). Among the parameter list is a name to
0020 identify the device under /sys/class/firmware. A user may initiate a
0021 firmware upload by echoing a 1 to the *loading* sysfs file for the target
0022 device. Next, the user writes the firmware image to the *data* sysfs
0023 file. After writing the firmware data, the user echos 0 to the *loading*
0024 sysfs file to signal completion. Echoing 0 to *loading* also triggers the
0025 transfer of the firmware to the lower-lever device driver in the context
0026 of a kernel worker thread.
0027 
0028 To use the firmware upload API, write a driver that implements a set of
0029 ops.  The probe function calls firmware_upload_register() and the remove
0030 function calls firmware_upload_unregister() such as::
0031 
0032         static const struct fw_upload_ops m10bmc_ops = {
0033                 .prepare = m10bmc_sec_prepare,
0034                 .write = m10bmc_sec_write,
0035                 .poll_complete = m10bmc_sec_poll_complete,
0036                 .cancel = m10bmc_sec_cancel,
0037                 .cleanup = m10bmc_sec_cleanup,
0038         };
0039 
0040         static int m10bmc_sec_probe(struct platform_device *pdev)
0041         {
0042                 const char *fw_name, *truncate;
0043                 struct m10bmc_sec *sec;
0044                 struct fw_upload *fwl;
0045                 unsigned int len;
0046 
0047                 sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL);
0048                 if (!sec)
0049                         return -ENOMEM;
0050 
0051                 sec->dev = &pdev->dev;
0052                 sec->m10bmc = dev_get_drvdata(pdev->dev.parent);
0053                 dev_set_drvdata(&pdev->dev, sec);
0054 
0055                 fw_name = dev_name(sec->dev);
0056                 truncate = strstr(fw_name, ".auto");
0057                 len = (truncate) ? truncate - fw_name : strlen(fw_name);
0058                 sec->fw_name = kmemdup_nul(fw_name, len, GFP_KERNEL);
0059 
0060                 fwl = firmware_upload_register(sec->dev, sec->fw_name, &m10bmc_ops, sec);
0061                 if (IS_ERR(fwl)) {
0062                         dev_err(sec->dev, "Firmware Upload driver failed to start\n");
0063                         kfree(sec->fw_name);
0064                         return PTR_ERR(fwl);
0065                 }
0066 
0067                 sec->fwl = fwl;
0068                 return 0;
0069         }
0070 
0071         static int m10bmc_sec_remove(struct platform_device *pdev)
0072         {
0073                 struct m10bmc_sec *sec = dev_get_drvdata(&pdev->dev);
0074 
0075                 firmware_upload_unregister(sec->fwl);
0076                 kfree(sec->fw_name);
0077                 return 0;
0078         }
0079 
0080 firmware_upload_register
0081 ------------------------
0082 .. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
0083    :identifiers: firmware_upload_register
0084 
0085 firmware_upload_unregister
0086 --------------------------
0087 .. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
0088    :identifiers: firmware_upload_unregister
0089 
0090 Firmware Upload Ops
0091 -------------------
0092 .. kernel-doc:: include/linux/firmware.h
0093    :identifiers: fw_upload_ops
0094 
0095 Firmware Upload Progress Codes
0096 ------------------------------
0097 The following progress codes are used internally by the firmware loader.
0098 Corresponding strings are reported through the status sysfs node that
0099 is described below and are documented in the ABI documentation.
0100 
0101 .. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.h
0102    :identifiers: fw_upload_prog
0103 
0104 Firmware Upload Error Codes
0105 ---------------------------
0106 The following error codes may be returned by the driver ops in case of
0107 failure:
0108 
0109 .. kernel-doc:: include/linux/firmware.h
0110    :identifiers: fw_upload_err
0111 
0112 Sysfs Attributes
0113 ================
0114 
0115 In addition to the *loading* and *data* sysfs files, there are additional
0116 sysfs files to monitor the status of the data transfer to the target
0117 device and to determine the final pass/fail status of the transfer.
0118 Depending on the device and the size of the firmware image, a firmware
0119 update could take milliseconds or minutes.
0120 
0121 The additional sysfs files are:
0122 
0123 * status - provides an indication of the progress of a firmware update
0124 * error - provides error information for a failed firmware update
0125 * remaining_size - tracks the data transfer portion of an update
0126 * cancel - echo 1 to this file to cancel the update