Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 811fa400 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

firmware_class: Split _request_firmware() into three functions, v2



Split _request_firmware() into three functions,
_request_firmware_prepare() doing preparatory work that need not be
done under umhelper_sem, _request_firmware_cleanup() doing the
post-error cleanup and _request_firmware() carrying out the remaining
operations.

This change is requisite for moving the acquisition of umhelper_sem
from _request_firmware() to the callers, which is going to be done
subsequently.

Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Cc: stable@vger.kernel.org
parent fe2e39d8
Loading
Loading
Loading
Loading
+41 −17
Original line number Diff line number Diff line
@@ -435,7 +435,7 @@ static void firmware_class_timeout(u_long data)
}

static struct firmware_priv *
fw_create_instance(struct firmware *firmware, const char *fw_name,
fw_create_instance(const struct firmware *firmware, const char *fw_name,
		   struct device *device, bool uevent, bool nowait)
{
	struct firmware_priv *fw_priv;
@@ -449,7 +449,7 @@ fw_create_instance(struct firmware *firmware, const char *fw_name,
		goto err_out;
	}

	fw_priv->fw = firmware;
	fw_priv->fw = (struct firmware *)firmware;
	fw_priv->nowait = nowait;
	strcpy(fw_priv->fw_id, fw_name);
	init_completion(&fw_priv->completion);
@@ -510,13 +510,10 @@ static void fw_destroy_instance(struct firmware_priv *fw_priv)
	device_unregister(f_dev);
}

static int _request_firmware(const struct firmware **firmware_p,
			     const char *name, struct device *device,
			     bool uevent, bool nowait)
static int _request_firmware_prepare(const struct firmware **firmware_p,
				     const char *name, struct device *device)
{
	struct firmware_priv *fw_priv;
	struct firmware *firmware;
	int retval = 0;

	if (!firmware_p)
		return -EINVAL;
@@ -533,10 +530,26 @@ static int _request_firmware(const struct firmware **firmware_p,
		return 0;
	}

	return 1;
}

static void _request_firmware_cleanup(const struct firmware **firmware_p)
{
	release_firmware(*firmware_p);
	*firmware_p = NULL;
}

static int _request_firmware(const struct firmware *firmware,
			     const char *name, struct device *device,
			     bool uevent, bool nowait)
{
	struct firmware_priv *fw_priv;
	int retval;

	retval = usermodehelper_read_trylock();
	if (WARN_ON(retval)) {
		dev_err(device, "firmware: %s will not be loaded\n", name);
		goto out_nolock;
		return retval;
	}

	if (uevent)
@@ -572,13 +585,6 @@ static int _request_firmware(const struct firmware **firmware_p,

out:
	usermodehelper_read_unlock();

out_nolock:
	if (retval) {
		release_firmware(firmware);
		*firmware_p = NULL;
	}

	return retval;
}

@@ -601,7 +607,17 @@ int
request_firmware(const struct firmware **firmware_p, const char *name,
                 struct device *device)
{
        return _request_firmware(firmware_p, name, device, true, false);
	int ret;

	ret = _request_firmware_prepare(firmware_p, name, device);
	if (ret <= 0)
		return ret;

	ret = _request_firmware(*firmware_p, name, device, true, false);
	if (ret)
		_request_firmware_cleanup(firmware_p);

	return ret;
}

/**
@@ -639,8 +655,16 @@ static int request_firmware_work_func(void *arg)
		return 0;
	}

	ret = _request_firmware(&fw, fw_work->name, fw_work->device,
	ret = _request_firmware_prepare(&fw, fw_work->name, fw_work->device);
	if (ret <= 0)
		goto out;

	ret = _request_firmware(fw, fw_work->name, fw_work->device,
				fw_work->uevent, true);
	if (ret)
		_request_firmware_cleanup(&fw);

 out:
	fw_work->cont(fw, fw_work->context);

	module_put(fw_work->module);