Commit 736da0b6 authored by Russ Weight's avatar Russ Weight Committed by Greg Kroah-Hartman
Browse files

firmware_loader: Check fw_state_is_done in loading_store



Rename fw_sysfs_done() and fw_sysfs_loading() to fw_state_is_done() and
fw_state_is_loading() respectively, and place them along side companion
functions in drivers/base/firmware_loader/firmware.h.

Use the fw_state_is_done() function to exit early from
firmware_loading_store() if the state is already "done". This is being done
in preparation for supporting persistent sysfs nodes to allow userspace to
upload firmware to a device, potentially reusing the sysfs loading and data
files multiple times.

Reviewed-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
Reviewed-by: default avatarTianfei zhang <tianfei.zhang@intel.com>
Tested-by: default avatarMatthew Gerlach <matthew.gerlach@linux.intel.com>
Signed-off-by: default avatarRuss Weight <russell.h.weight@intel.com>
Link: https://lore.kernel.org/r/20220421212204.36052-3-russell.h.weight@intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4ac4a90d
Loading
Loading
Loading
Loading
+8 −20
Original line number Diff line number Diff line
@@ -58,16 +58,6 @@ static long firmware_loading_timeout(void)
		__firmware_loading_timeout() * HZ : MAX_JIFFY_OFFSET;
}

static inline bool fw_sysfs_done(struct fw_priv *fw_priv)
{
	return __fw_state_check(fw_priv, FW_STATUS_DONE);
}

static inline bool fw_sysfs_loading(struct fw_priv *fw_priv)
{
	return __fw_state_check(fw_priv, FW_STATUS_LOADING);
}

static inline int fw_sysfs_wait_timeout(struct fw_priv *fw_priv,  long timeout)
{
	return __fw_state_wait_common(fw_priv, timeout);
@@ -91,7 +81,7 @@ static 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_sysfs_done(fw_priv))
	if (fw_state_is_aborted(fw_priv) || fw_state_is_done(fw_priv))
		return;

	fw_state_aborted(fw_priv);
@@ -220,7 +210,7 @@ static ssize_t firmware_loading_show(struct device *dev,

	mutex_lock(&fw_lock);
	if (fw_sysfs->fw_priv)
		loading = fw_sysfs_loading(fw_sysfs->fw_priv);
		loading = fw_state_is_loading(fw_sysfs->fw_priv);
	mutex_unlock(&fw_lock);

	return sysfs_emit(buf, "%d\n", loading);
@@ -250,19 +240,17 @@ static ssize_t firmware_loading_store(struct device *dev,

	mutex_lock(&fw_lock);
	fw_priv = fw_sysfs->fw_priv;
	if (fw_state_is_aborted(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 */
		if (!fw_sysfs_done(fw_priv)) {
		fw_free_paged_buf(fw_priv);
		fw_state_start(fw_priv);
		}
		break;
	case 0:
		if (fw_sysfs_loading(fw_priv)) {
		if (fw_state_is_loading(fw_priv)) {
			int rc;

			/*
@@ -350,7 +338,7 @@ static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj,

	mutex_lock(&fw_lock);
	fw_priv = fw_sysfs->fw_priv;
	if (!fw_priv || fw_sysfs_done(fw_priv)) {
	if (!fw_priv || fw_state_is_done(fw_priv)) {
		ret_count = -ENODEV;
		goto out;
	}
@@ -410,7 +398,7 @@ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj,

	mutex_lock(&fw_lock);
	fw_priv = fw_sysfs->fw_priv;
	if (!fw_priv || fw_sysfs_done(fw_priv)) {
	if (!fw_priv || fw_state_is_done(fw_priv)) {
		retval = -ENODEV;
		goto out;
	}
+10 −0
Original line number Diff line number Diff line
@@ -149,6 +149,16 @@ static inline void fw_state_done(struct fw_priv *fw_priv)
	__fw_state_set(fw_priv, FW_STATUS_DONE);
}

static inline bool fw_state_is_done(struct fw_priv *fw_priv)
{
	return __fw_state_check(fw_priv, FW_STATUS_DONE);
}

static inline bool fw_state_is_loading(struct fw_priv *fw_priv)
{
	return __fw_state_check(fw_priv, FW_STATUS_LOADING);
}

int assign_fw(struct firmware *fw, struct device *device);

#ifdef CONFIG_FW_LOADER