void __fw_load_abort(struct fw_priv *fw_priv)
{ /* * There is a small window in which user can write to 'loading' * between loading done/aborted and disappearance of 'loading'
*/ if (fw_state_is_aborted(fw_priv) || fw_state_is_done(fw_priv)) return;
/** * timeout_store() - set number of seconds to wait for firmware * @class: device class pointer * @attr: device attribute pointer * @buf: buffer to scan for timeout value * @count: number of bytes in @buf * * Sets the number of seconds to wait for the firmware. Once * this expires an error will be returned to the driver and no * firmware will be provided. * * Note: zero means 'wait forever'.
**/ static ssize_t timeout_store(conststructclass *class, conststruct class_attribute *attr, constchar *buf, size_t count)
{ int tmp_loading_timeout = simple_strtol(buf, NULL, 10);
if (tmp_loading_timeout < 0)
tmp_loading_timeout = 0;
mutex_lock(&fw_lock); if (fw_sysfs->fw_priv)
loading = fw_state_is_loading(fw_sysfs->fw_priv);
mutex_unlock(&fw_lock);
return sysfs_emit(buf, "%d\n", loading);
}
/** * firmware_loading_store() - set value in the 'loading' control file * @dev: device pointer * @attr: device attribute pointer * @buf: buffer to scan for loading control value * @count: number of bytes in @buf * * The relevant values are: * * 1: Start a load, discarding any previous partial load. * 0: Conclude the load and hand the data to the driver code. * -1: Conclude the load with an error and discard any written data.
**/ static ssize_t firmware_loading_store(struct device *dev, struct device_attribute *attr, constchar *buf, size_t count)
{ struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); struct fw_priv *fw_priv;
ssize_t written = count; int loading = simple_strtol(buf, NULL, 10);
mutex_lock(&fw_lock);
fw_priv = fw_sysfs->fw_priv; if (fw_state_is_aborted(fw_priv) || fw_state_is_done(fw_priv)) goto out;
switch (loading) { case 1: /* discarding any previous partial load */
fw_free_paged_buf(fw_priv);
fw_state_start(fw_priv); break; case 0: if (fw_state_is_loading(fw_priv)) { int rc;
/* * Several loading requests may be pending on * one same firmware buf, so let all requests * see the mapped 'buf->data' once the loading * is completed.
*/
rc = fw_map_paged_buf(fw_priv); if (rc)
dev_err(dev, "%s: map pages failed\n",
__func__); else
rc = security_kernel_post_load_data(fw_priv->data,
fw_priv->size,
LOADING_FIRMWARE, "blob");
/* * Same logic as fw_load_abort, only the DONE bit * is ignored and we set ABORT only on failure.
*/ if (rc) {
fw_state_aborted(fw_priv);
written = rc;
} else {
fw_state_done(fw_priv);
/* * If this is a user-initiated firmware upload * then start the upload in a worker thread now.
*/
rc = fw_upload_start(fw_sysfs); if (rc)
written = rc;
} break;
}
fallthrough; default:
dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading);
fallthrough; case -1:
fw_load_abort(fw_sysfs); if (fw_sysfs->fw_upload_priv)
fw_state_init(fw_sysfs->fw_priv);
/** * firmware_data_write() - write method for firmware * @filp: open sysfs file * @kobj: kobject for the device * @bin_attr: bin_attr structure * @buffer: buffer being written * @offset: buffer offset for write in total data store area * @count: buffer size * * Data written to the 'data' attribute will be later handed to * the driver as a firmware image.
**/ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, conststruct bin_attribute *bin_attr, char *buffer, loff_t offset, size_t count)
{ struct device *dev = kobj_to_dev(kobj); struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); struct fw_priv *fw_priv;
ssize_t retval;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.