diff options
Diffstat (limited to 'lib/test_firmware.c')
| -rw-r--r-- | lib/test_firmware.c | 154 | 
1 files changed, 142 insertions, 12 deletions
diff --git a/lib/test_firmware.c b/lib/test_firmware.c index 06c955057756..2baa275a6ddf 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -52,6 +52,9 @@ struct test_batched_req {   * @name: the name of the firmware file to look for   * @into_buf: when the into_buf is used if this is true   *	request_firmware_into_buf() will be used instead. + * @buf_size: size of buf to allocate when into_buf is true + * @file_offset: file offset to request when calling request_firmware_into_buf + * @partial: partial read opt when calling request_firmware_into_buf   * @sync_direct: when the sync trigger is used if this is true   *	request_firmware_direct() will be used instead.   * @send_uevent: whether or not to send a uevent for async requests @@ -91,6 +94,9 @@ struct test_batched_req {  struct test_config {  	char *name;  	bool into_buf; +	size_t buf_size; +	size_t file_offset; +	bool partial;  	bool sync_direct;  	bool send_uevent;  	u8 num_requests; @@ -185,6 +191,9 @@ static int __test_firmware_config_init(void)  	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; @@ -238,28 +247,35 @@ static ssize_t config_show(struct device *dev,  			dev_name(dev));  	if (test_fw_config->name) -		len += scnprintf(buf+len, PAGE_SIZE - len, +		len += scnprintf(buf + len, PAGE_SIZE - len,  				"name:\t%s\n",  				test_fw_config->name);  	else -		len += scnprintf(buf+len, PAGE_SIZE - len, +		len += scnprintf(buf + len, PAGE_SIZE - len,  				"name:\tEMTPY\n"); -	len += scnprintf(buf+len, PAGE_SIZE - len, +	len += scnprintf(buf + len, PAGE_SIZE - len,  			"num_requests:\t%u\n", test_fw_config->num_requests); -	len += scnprintf(buf+len, PAGE_SIZE - len, +	len += scnprintf(buf + len, PAGE_SIZE - len,  			"send_uevent:\t\t%s\n",  			test_fw_config->send_uevent ?  			"FW_ACTION_HOTPLUG" :  			"FW_ACTION_NOHOTPLUG"); -	len += scnprintf(buf+len, PAGE_SIZE - len, +	len += scnprintf(buf + len, PAGE_SIZE - len,  			"into_buf:\t\t%s\n",  			test_fw_config->into_buf ? "true" : "false"); -	len += scnprintf(buf+len, PAGE_SIZE - len, +	len += scnprintf(buf + len, PAGE_SIZE - len, +			"buf_size:\t%zu\n", test_fw_config->buf_size); +	len += scnprintf(buf + len, PAGE_SIZE - len, +			"file_offset:\t%zu\n", test_fw_config->file_offset); +	len += scnprintf(buf + len, PAGE_SIZE - len, +			"partial:\t\t%s\n", +			test_fw_config->partial ? "true" : "false"); +	len += scnprintf(buf + len, PAGE_SIZE - len,  			"sync_direct:\t\t%s\n",  			test_fw_config->sync_direct ? "true" : "false"); -	len += scnprintf(buf+len, PAGE_SIZE - len, +	len += scnprintf(buf + len, PAGE_SIZE - len,  			"read_fw_idx:\t%u\n", test_fw_config->read_fw_idx);  	mutex_unlock(&test_fw_mutex); @@ -317,6 +333,30 @@ static ssize_t test_dev_config_show_bool(char *buf, bool val)  	return snprintf(buf, PAGE_SIZE, "%d\n", val);  } +static int test_dev_config_update_size_t(const char *buf, +					 size_t size, +					 size_t *cfg) +{ +	int ret; +	long new; + +	ret = kstrtol(buf, 10, &new); +	if (ret) +		return ret; + +	mutex_lock(&test_fw_mutex); +	*(size_t *)cfg = new; +	mutex_unlock(&test_fw_mutex); + +	/* Always return full write size even if we didn't consume all */ +	return size; +} + +static ssize_t test_dev_config_show_size_t(char *buf, size_t val) +{ +	return snprintf(buf, PAGE_SIZE, "%zu\n", val); +} +  static ssize_t test_dev_config_show_int(char *buf, int val)  {  	return snprintf(buf, PAGE_SIZE, "%d\n", val); @@ -402,6 +442,83 @@ static ssize_t config_into_buf_show(struct device *dev,  }  static DEVICE_ATTR_RW(config_into_buf); +static ssize_t config_buf_size_store(struct device *dev, +				     struct device_attribute *attr, +				     const char *buf, size_t count) +{ +	int rc; + +	mutex_lock(&test_fw_mutex); +	if (test_fw_config->reqs) { +		pr_err("Must call release_all_firmware prior to changing config\n"); +		rc = -EINVAL; +		mutex_unlock(&test_fw_mutex); +		goto out; +	} +	mutex_unlock(&test_fw_mutex); + +	rc = test_dev_config_update_size_t(buf, count, +					   &test_fw_config->buf_size); + +out: +	return rc; +} + +static ssize_t config_buf_size_show(struct device *dev, +				    struct device_attribute *attr, +				    char *buf) +{ +	return test_dev_config_show_size_t(buf, test_fw_config->buf_size); +} +static DEVICE_ATTR_RW(config_buf_size); + +static ssize_t config_file_offset_store(struct device *dev, +					struct device_attribute *attr, +					const char *buf, size_t count) +{ +	int rc; + +	mutex_lock(&test_fw_mutex); +	if (test_fw_config->reqs) { +		pr_err("Must call release_all_firmware prior to changing config\n"); +		rc = -EINVAL; +		mutex_unlock(&test_fw_mutex); +		goto out; +	} +	mutex_unlock(&test_fw_mutex); + +	rc = test_dev_config_update_size_t(buf, count, +					   &test_fw_config->file_offset); + +out: +	return rc; +} + +static ssize_t config_file_offset_show(struct device *dev, +				       struct device_attribute *attr, +				       char *buf) +{ +	return test_dev_config_show_size_t(buf, test_fw_config->file_offset); +} +static DEVICE_ATTR_RW(config_file_offset); + +static ssize_t config_partial_store(struct device *dev, +				    struct device_attribute *attr, +				    const char *buf, size_t count) +{ +	return test_dev_config_update_bool(buf, +					   count, +					   &test_fw_config->partial); +} + +static ssize_t config_partial_show(struct device *dev, +				   struct device_attribute *attr, +				   char *buf) +{ +	return test_dev_config_show_bool(buf, test_fw_config->partial); +} +static DEVICE_ATTR_RW(config_partial); +  static ssize_t config_sync_direct_store(struct device *dev,  					struct device_attribute *attr,  					const char *buf, size_t count) @@ -659,11 +776,21 @@ static int test_fw_run_batch_request(void *data)  		if (!test_buf)  			return -ENOSPC; -		req->rc = request_firmware_into_buf(&req->fw, -						    req->name, -						    req->dev, -						    test_buf, -						    TEST_FIRMWARE_BUF_SIZE); +		if (test_fw_config->partial) +			req->rc = request_partial_firmware_into_buf +						(&req->fw, +						 req->name, +						 req->dev, +						 test_buf, +						 test_fw_config->buf_size, +						 test_fw_config->file_offset); +		else +			req->rc = request_firmware_into_buf +						(&req->fw, +						 req->name, +						 req->dev, +						 test_buf, +						 test_fw_config->buf_size);  		if (!req->fw)  			kfree(test_buf);  	} else { @@ -936,6 +1063,9 @@ static struct attribute *test_dev_attrs[] = {  	TEST_FW_DEV_ATTR(config_name),  	TEST_FW_DEV_ATTR(config_num_requests),  	TEST_FW_DEV_ATTR(config_into_buf), +	TEST_FW_DEV_ATTR(config_buf_size), +	TEST_FW_DEV_ATTR(config_file_offset), +	TEST_FW_DEV_ATTR(config_partial),  	TEST_FW_DEV_ATTR(config_sync_direct),  	TEST_FW_DEV_ATTR(config_send_uevent),  	TEST_FW_DEV_ATTR(config_read_fw_idx),  | 
