lib/test_firmware.c

Source file repositories/reference/linux-study-clean/lib/test_firmware.c

File Facts

System
Linux kernel
Corpus path
lib/test_firmware.c
Extension
.c
Size
38391 bytes
Lines
1573
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations test_fw_fops = {
	.owner          = THIS_MODULE,
	.read           = test_fw_misc_read,
};

static void __test_release_all_firmware(void)
{
	struct test_batched_req *req;
	u8 i;

	if (!test_fw_config->reqs)
		return;

	for (i = 0; i < test_fw_config->num_requests; i++) {
		req = &test_fw_config->reqs[i];
		if (req->fw) {
			if (req->fw_buf) {
				kfree_const(req->fw_buf);
				req->fw_buf = NULL;
			}
			release_firmware(req->fw);
			req->fw = NULL;
		}
	}

	vfree(test_fw_config->reqs);
	test_fw_config->reqs = NULL;
}

static void test_release_all_firmware(void)
{
	mutex_lock(&test_fw_mutex);
	__test_release_all_firmware();
	mutex_unlock(&test_fw_mutex);
}


static void __test_firmware_config_free(void)
{
	__test_release_all_firmware();
	kfree_const(test_fw_config->name);
	test_fw_config->name = NULL;
}

/*
 * XXX: move to kstrncpy() once merged.
 *
 * Users should use kfree_const() when freeing these.
 */
static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp)
{
	*dst = kstrndup(name, count, gfp);
	if (!*dst)
		return -ENOMEM;
	return count;
}

static int __test_firmware_config_init(void)
{
	int ret;

	ret = __kstrncpy(&test_fw_config->name, TEST_FIRMWARE_NAME,
			 strlen(TEST_FIRMWARE_NAME), GFP_KERNEL);
	if (ret < 0)
		goto out;

	test_fw_config->num_requests = TEST_FIRMWARE_NUM_REQS;
	test_fw_config->send_uevent = true;
	test_fw_config->into_buf = false;
	test_fw_config->buf_size = TEST_FIRMWARE_BUF_SIZE;
	test_fw_config->file_offset = 0;
	test_fw_config->partial = false;
	test_fw_config->sync_direct = false;
	test_fw_config->req_firmware = request_firmware;
	test_fw_config->test_result = 0;
	test_fw_config->reqs = NULL;
	test_fw_config->upload_name = NULL;

	return 0;

out:
	__test_firmware_config_free();
	return ret;
}

static ssize_t reset_store(struct device *dev,
			   struct device_attribute *attr,
			   const char *buf, size_t count)
{
	int ret;

Annotation

Implementation Notes