static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj,
				   struct 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;

	if (!capable(CAP_SYS_RAWIO))
		return -EPERM;

	mutex_lock(&fw_lock);
	fw_priv = fw_sysfs->fw_priv;
	if (!fw_priv || fw_sysfs_done(fw_priv)) {
		retval = -ENODEV;
		goto out;
	}

	if (fw_priv->data) {
		if (offset + count > fw_priv->allocated_size) {
			retval = -ENOMEM;
			goto out;
		}
		firmware_rw_data(fw_priv, buffer, offset, count, false);
		retval = count;
	} else {
		retval = fw_realloc_pages(fw_sysfs, offset + count);
		if (retval)
			goto out;

		retval = count;
		firmware_rw(fw_priv, buffer, offset, count, false);
	}

	fw_priv->size = max_t(size_t, offset + count, fw_priv->size);
out:
	mutex_unlock(&fw_lock);
	return retval;
}
static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj,
				   struct 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;

	if (!capable(CAP_SYS_RAWIO))
		return -EPERM;

	mutex_lock(&fw_lock);
	fw_priv = fw_sysfs->fw_priv;
	if (!fw_priv || fw_sysfs_done(fw_priv)) {
		retval = -ENODEV;
		goto out;
	}

	if (fw_priv->data) {
		if (offset + count > fw_priv->allocated_size) {
			retval = -ENOMEM;
			goto out;
		}
		firmware_rw_data(fw_priv, buffer, offset, count, false);
		retval = count;
	} else {
		retval = fw_realloc_pages(fw_sysfs, offset + count);
		if (retval)
			goto out;

		retval = count;
		firmware_rw(fw_priv, buffer, offset, count, false);
	}

	fw_priv->size = max_t(size_t, offset + count, fw_priv->size);
out:
	mutex_unlock(&fw_lock);
	return retval;
}