fw_upload_update_progress(fwlp, FW_UPLOAD_PROG_PROGRAMMING);
ret = fwlp->ops->poll_complete(fwl); if (ret != FW_UPLOAD_ERR_NONE)
fw_upload_set_error(fwlp, ret);
done: if (fwlp->ops->cleanup)
fwlp->ops->cleanup(fwl);
putdev_exit:
put_device(fw_dev->parent);
/* * Note: fwlp->remaining_size is left unmodified here to provide * additional information on errors. It will be reinitialized when * the next firmeware upload begins.
*/
mutex_lock(&fw_lock);
fw_free_paged_buf(fw_sysfs->fw_priv);
fw_state_init(fw_sysfs->fw_priv);
mutex_unlock(&fw_lock);
fwlp->data = NULL;
fw_upload_prog_complete(fwlp);
}
/* * Start a worker thread to upload data to the parent driver. * Must be called with fw_lock held.
*/ int fw_upload_start(struct fw_sysfs *fw_sysfs)
{ struct fw_priv *fw_priv = fw_sysfs->fw_priv; struct device *fw_dev = &fw_sysfs->dev; struct fw_upload_priv *fwlp;
if (!fw_sysfs->fw_upload_priv) return 0;
if (!fw_priv->size) {
fw_free_paged_buf(fw_priv);
fw_state_init(fw_sysfs->fw_priv); return 0;
}
/** * firmware_upload_register() - register for the firmware upload sysfs API * @module: kernel module of this device * @parent: parent device instantiating firmware upload * @name: firmware name to be associated with this device * @ops: pointer to structure of firmware upload ops * @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() *
**/ struct fw_upload *
firmware_upload_register(struct module *module, struct device *parent, constchar *name, conststruct fw_upload_ops *ops, void *dd_handle)
{
u32 opt_flags = FW_OPT_NOCACHE; struct fw_upload *fw_upload; struct fw_upload_priv *fw_upload_priv; struct fw_sysfs *fw_sysfs; struct fw_priv *fw_priv; struct device *fw_dev; int ret;
if (!name || name[0] == '\0') return ERR_PTR(-EINVAL);
if (!ops || !ops->cancel || !ops->prepare ||
!ops->write || !ops->poll_complete) {
dev_err(parent, "Attempt to register without all required ops\n"); return ERR_PTR(-EINVAL);
}
if (!try_module_get(module)) return ERR_PTR(-EFAULT);
fw_upload = kzalloc(sizeof(*fw_upload), GFP_KERNEL); if (!fw_upload) {
ret = -ENOMEM; goto exit_module_put;
}
fw_upload_priv = kzalloc(sizeof(*fw_upload_priv), GFP_KERNEL); if (!fw_upload_priv) {
ret = -ENOMEM; goto free_fw_upload;
}
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.