ublk_drv: add mechanism for supporting unprivileged ublk device
[linux-block.git] / lib / test_firmware.c
CommitLineData
09c434b8 1// SPDX-License-Identifier: GPL-2.0-only
0a8adf58
KC
2/*
3 * This module provides an interface to trigger and test firmware loading.
4 *
5 * It is designed to be used for basic evaluation of the firmware loading
6 * subsystem (for example when validating firmware verification). It lacks
7 * any extra dependencies, and will not normally be loaded by the system
8 * unless explicitly requested by name.
9 */
10
11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/printk.h>
eb910947 16#include <linux/completion.h>
0a8adf58
KC
17#include <linux/firmware.h>
18#include <linux/device.h>
19#include <linux/fs.h>
20#include <linux/miscdevice.h>
7feebfa4 21#include <linux/sizes.h>
0a8adf58
KC
22#include <linux/slab.h>
23#include <linux/uaccess.h>
c92316bf
LR
24#include <linux/delay.h>
25#include <linux/kthread.h>
514c6032 26#include <linux/vmalloc.h>
548193cb 27#include <linux/efi_embedded_fw.h>
c92316bf 28
baaabecf
KC
29MODULE_IMPORT_NS(TEST_FIRMWARE);
30
c92316bf
LR
31#define TEST_FIRMWARE_NAME "test-firmware.bin"
32#define TEST_FIRMWARE_NUM_REQS 4
7feebfa4 33#define TEST_FIRMWARE_BUF_SIZE SZ_1K
a31ad463
RW
34#define TEST_UPLOAD_MAX_SIZE SZ_2K
35#define TEST_UPLOAD_BLK_SIZE 37 /* Avoid powers of two in testing */
0a8adf58
KC
36
37static DEFINE_MUTEX(test_fw_mutex);
38static const struct firmware *test_firmware;
a31ad463 39static LIST_HEAD(test_upload_list);
0a8adf58 40
c92316bf
LR
41struct test_batched_req {
42 u8 idx;
43 int rc;
44 bool sent;
45 const struct firmware *fw;
46 const char *name;
47 struct completion completion;
48 struct task_struct *task;
49 struct device *dev;
50};
51
52/**
53 * test_config - represents configuration for the test for different triggers
54 *
55 * @name: the name of the firmware file to look for
7feebfa4
SB
56 * @into_buf: when the into_buf is used if this is true
57 * request_firmware_into_buf() will be used instead.
5d90e05c
SB
58 * @buf_size: size of buf to allocate when into_buf is true
59 * @file_offset: file offset to request when calling request_firmware_into_buf
60 * @partial: partial read opt when calling request_firmware_into_buf
c92316bf
LR
61 * @sync_direct: when the sync trigger is used if this is true
62 * request_firmware_direct() will be used instead.
63 * @send_uevent: whether or not to send a uevent for async requests
64 * @num_requests: number of requests to try per test case. This is trigger
65 * specific.
66 * @reqs: stores all requests information
67 * @read_fw_idx: index of thread from which we want to read firmware results
68 * from through the read_fw trigger.
a31ad463 69 * @upload_name: firmware name to be used with upload_read sysfs node
c92316bf
LR
70 * @test_result: a test may use this to collect the result from the call
71 * of the request_firmware*() calls used in their tests. In order of
72 * priority we always keep first any setup error. If no setup errors were
73 * found then we move on to the first error encountered while running the
74 * API. Note that for async calls this typically will be a successful
75 * result (0) unless of course you've used bogus parameters, or the system
76 * is out of memory. In the async case the callback is expected to do a
77 * bit more homework to figure out what happened, unfortunately the only
78 * information passed today on error is the fact that no firmware was
79 * found so we can only assume -ENOENT on async calls if the firmware is
80 * NULL.
81 *
82 * Errors you can expect:
83 *
84 * API specific:
85 *
86 * 0: success for sync, for async it means request was sent
87 * -EINVAL: invalid parameters or request
88 * -ENOENT: files not found
89 *
90 * System environment:
91 *
92 * -ENOMEM: memory pressure on system
93 * -ENODEV: out of number of devices to test
94 * -EINVAL: an unexpected error has occurred
95 * @req_firmware: if @sync_direct is true this is set to
96 * request_firmware_direct(), otherwise request_firmware()
97 */
98struct test_config {
99 char *name;
7feebfa4 100 bool into_buf;
5d90e05c
SB
101 size_t buf_size;
102 size_t file_offset;
103 bool partial;
c92316bf
LR
104 bool sync_direct;
105 bool send_uevent;
106 u8 num_requests;
107 u8 read_fw_idx;
a31ad463 108 char *upload_name;
c92316bf
LR
109
110 /*
111 * These below don't belong her but we'll move them once we create
112 * a struct fw_test_device and stuff the misc_dev under there later.
113 */
114 struct test_batched_req *reqs;
115 int test_result;
116 int (*req_firmware)(const struct firmware **fw, const char *name,
117 struct device *device);
118};
119
4a4e975b
RW
120struct upload_inject_err {
121 const char *prog;
122 enum fw_upload_err err_code;
123};
124
a31ad463
RW
125struct test_firmware_upload {
126 char *name;
127 struct list_head node;
128 char *buf;
129 size_t size;
130 bool cancel_request;
4a4e975b 131 struct upload_inject_err inject;
a31ad463
RW
132 struct fw_upload *fwl;
133};
134
76f8ab1b 135static struct test_config *test_fw_config;
c92316bf 136
a31ad463
RW
137static struct test_firmware_upload *upload_lookup_name(const char *name)
138{
139 struct test_firmware_upload *tst;
140
141 list_for_each_entry(tst, &test_upload_list, node)
142 if (strncmp(name, tst->name, strlen(tst->name)) == 0)
143 return tst;
144
145 return NULL;
146}
147
0a8adf58
KC
148static ssize_t test_fw_misc_read(struct file *f, char __user *buf,
149 size_t size, loff_t *offset)
150{
151 ssize_t rc = 0;
152
153 mutex_lock(&test_fw_mutex);
154 if (test_firmware)
155 rc = simple_read_from_buffer(buf, size, offset,
156 test_firmware->data,
157 test_firmware->size);
158 mutex_unlock(&test_fw_mutex);
159 return rc;
160}
161
162static const struct file_operations test_fw_fops = {
163 .owner = THIS_MODULE,
164 .read = test_fw_misc_read,
165};
166
c92316bf
LR
167static void __test_release_all_firmware(void)
168{
169 struct test_batched_req *req;
170 u8 i;
171
172 if (!test_fw_config->reqs)
173 return;
174
175 for (i = 0; i < test_fw_config->num_requests; i++) {
176 req = &test_fw_config->reqs[i];
177 if (req->fw)
178 release_firmware(req->fw);
179 }
180
181 vfree(test_fw_config->reqs);
182 test_fw_config->reqs = NULL;
183}
184
185static void test_release_all_firmware(void)
186{
187 mutex_lock(&test_fw_mutex);
188 __test_release_all_firmware();
189 mutex_unlock(&test_fw_mutex);
190}
191
192
193static void __test_firmware_config_free(void)
194{
195 __test_release_all_firmware();
196 kfree_const(test_fw_config->name);
197 test_fw_config->name = NULL;
198}
199
200/*
201 * XXX: move to kstrncpy() once merged.
202 *
203 * Users should use kfree_const() when freeing these.
204 */
205static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp)
206{
207 *dst = kstrndup(name, count, gfp);
208 if (!*dst)
209 return -ENOSPC;
210 return count;
211}
212
213static int __test_firmware_config_init(void)
214{
215 int ret;
216
217 ret = __kstrncpy(&test_fw_config->name, TEST_FIRMWARE_NAME,
218 strlen(TEST_FIRMWARE_NAME), GFP_KERNEL);
219 if (ret < 0)
220 goto out;
221
222 test_fw_config->num_requests = TEST_FIRMWARE_NUM_REQS;
223 test_fw_config->send_uevent = true;
7feebfa4 224 test_fw_config->into_buf = false;
5d90e05c
SB
225 test_fw_config->buf_size = TEST_FIRMWARE_BUF_SIZE;
226 test_fw_config->file_offset = 0;
227 test_fw_config->partial = false;
c92316bf
LR
228 test_fw_config->sync_direct = false;
229 test_fw_config->req_firmware = request_firmware;
230 test_fw_config->test_result = 0;
231 test_fw_config->reqs = NULL;
a31ad463 232 test_fw_config->upload_name = NULL;
c92316bf
LR
233
234 return 0;
235
236out:
237 __test_firmware_config_free();
238 return ret;
239}
240
241static ssize_t reset_store(struct device *dev,
242 struct device_attribute *attr,
243 const char *buf, size_t count)
244{
245 int ret;
246
247 mutex_lock(&test_fw_mutex);
248
249 __test_firmware_config_free();
250
251 ret = __test_firmware_config_init();
252 if (ret < 0) {
253 ret = -ENOMEM;
254 pr_err("could not alloc settings for config trigger: %d\n",
255 ret);
256 goto out;
257 }
258
259 pr_info("reset\n");
260 ret = count;
261
262out:
263 mutex_unlock(&test_fw_mutex);
264
265 return ret;
266}
267static DEVICE_ATTR_WO(reset);
268
269static ssize_t config_show(struct device *dev,
270 struct device_attribute *attr,
271 char *buf)
272{
273 int len = 0;
274
275 mutex_lock(&test_fw_mutex);
276
bd17cc5a 277 len += scnprintf(buf, PAGE_SIZE - len,
c92316bf
LR
278 "Custom trigger configuration for: %s\n",
279 dev_name(dev));
280
281 if (test_fw_config->name)
5d90e05c 282 len += scnprintf(buf + len, PAGE_SIZE - len,
c92316bf
LR
283 "name:\t%s\n",
284 test_fw_config->name);
285 else
5d90e05c 286 len += scnprintf(buf + len, PAGE_SIZE - len,
d88bd098 287 "name:\tEMPTY\n");
c92316bf 288
5d90e05c 289 len += scnprintf(buf + len, PAGE_SIZE - len,
c92316bf
LR
290 "num_requests:\t%u\n", test_fw_config->num_requests);
291
5d90e05c 292 len += scnprintf(buf + len, PAGE_SIZE - len,
c92316bf
LR
293 "send_uevent:\t\t%s\n",
294 test_fw_config->send_uevent ?
0733d839
SG
295 "FW_ACTION_UEVENT" :
296 "FW_ACTION_NOUEVENT");
5d90e05c 297 len += scnprintf(buf + len, PAGE_SIZE - len,
7feebfa4
SB
298 "into_buf:\t\t%s\n",
299 test_fw_config->into_buf ? "true" : "false");
5d90e05c
SB
300 len += scnprintf(buf + len, PAGE_SIZE - len,
301 "buf_size:\t%zu\n", test_fw_config->buf_size);
302 len += scnprintf(buf + len, PAGE_SIZE - len,
303 "file_offset:\t%zu\n", test_fw_config->file_offset);
304 len += scnprintf(buf + len, PAGE_SIZE - len,
305 "partial:\t\t%s\n",
306 test_fw_config->partial ? "true" : "false");
307 len += scnprintf(buf + len, PAGE_SIZE - len,
c92316bf
LR
308 "sync_direct:\t\t%s\n",
309 test_fw_config->sync_direct ? "true" : "false");
5d90e05c 310 len += scnprintf(buf + len, PAGE_SIZE - len,
c92316bf 311 "read_fw_idx:\t%u\n", test_fw_config->read_fw_idx);
a31ad463
RW
312 if (test_fw_config->upload_name)
313 len += scnprintf(buf + len, PAGE_SIZE - len,
314 "upload_name:\t%s\n",
315 test_fw_config->upload_name);
316 else
317 len += scnprintf(buf + len, PAGE_SIZE - len,
d88bd098 318 "upload_name:\tEMPTY\n");
c92316bf
LR
319
320 mutex_unlock(&test_fw_mutex);
321
322 return len;
323}
324static DEVICE_ATTR_RO(config);
325
326static ssize_t config_name_store(struct device *dev,
327 struct device_attribute *attr,
328 const char *buf, size_t count)
329{
330 int ret;
331
332 mutex_lock(&test_fw_mutex);
333 kfree_const(test_fw_config->name);
334 ret = __kstrncpy(&test_fw_config->name, buf, count, GFP_KERNEL);
335 mutex_unlock(&test_fw_mutex);
336
337 return ret;
338}
339
340/*
341 * As per sysfs_kf_seq_show() the buf is max PAGE_SIZE.
342 */
343static ssize_t config_test_show_str(char *dst,
344 char *src)
345{
346 int len;
347
348 mutex_lock(&test_fw_mutex);
349 len = snprintf(dst, PAGE_SIZE, "%s\n", src);
350 mutex_unlock(&test_fw_mutex);
351
352 return len;
353}
354
355static int test_dev_config_update_bool(const char *buf, size_t size,
356 bool *cfg)
357{
358 int ret;
359
360 mutex_lock(&test_fw_mutex);
361 if (strtobool(buf, cfg) < 0)
362 ret = -EINVAL;
363 else
364 ret = size;
365 mutex_unlock(&test_fw_mutex);
366
367 return ret;
368}
369
55623260 370static ssize_t test_dev_config_show_bool(char *buf, bool val)
c92316bf 371{
c92316bf
LR
372 return snprintf(buf, PAGE_SIZE, "%d\n", val);
373}
374
5d90e05c
SB
375static int test_dev_config_update_size_t(const char *buf,
376 size_t size,
377 size_t *cfg)
378{
379 int ret;
380 long new;
381
382 ret = kstrtol(buf, 10, &new);
383 if (ret)
384 return ret;
385
386 mutex_lock(&test_fw_mutex);
387 *(size_t *)cfg = new;
388 mutex_unlock(&test_fw_mutex);
389
390 /* Always return full write size even if we didn't consume all */
391 return size;
392}
393
394static ssize_t test_dev_config_show_size_t(char *buf, size_t val)
395{
396 return snprintf(buf, PAGE_SIZE, "%zu\n", val);
397}
398
55623260 399static ssize_t test_dev_config_show_int(char *buf, int val)
c92316bf 400{
c92316bf
LR
401 return snprintf(buf, PAGE_SIZE, "%d\n", val);
402}
403
404static int test_dev_config_update_u8(const char *buf, size_t size, u8 *cfg)
405{
506dfc99 406 u8 val;
c92316bf 407 int ret;
c92316bf 408
506dfc99 409 ret = kstrtou8(buf, 10, &val);
c92316bf
LR
410 if (ret)
411 return ret;
412
c92316bf 413 mutex_lock(&test_fw_mutex);
506dfc99 414 *(u8 *)cfg = val;
c92316bf
LR
415 mutex_unlock(&test_fw_mutex);
416
417 /* Always return full write size even if we didn't consume all */
418 return size;
419}
420
55623260 421static ssize_t test_dev_config_show_u8(char *buf, u8 val)
c92316bf 422{
c92316bf
LR
423 return snprintf(buf, PAGE_SIZE, "%u\n", val);
424}
425
426static ssize_t config_name_show(struct device *dev,
427 struct device_attribute *attr,
428 char *buf)
429{
430 return config_test_show_str(buf, test_fw_config->name);
431}
b6b996b6 432static DEVICE_ATTR_RW(config_name);
c92316bf 433
a31ad463
RW
434static ssize_t config_upload_name_store(struct device *dev,
435 struct device_attribute *attr,
436 const char *buf, size_t count)
437{
438 struct test_firmware_upload *tst;
439 int ret = count;
440
441 mutex_lock(&test_fw_mutex);
442 tst = upload_lookup_name(buf);
443 if (tst)
444 test_fw_config->upload_name = tst->name;
445 else
446 ret = -EINVAL;
447 mutex_unlock(&test_fw_mutex);
448
449 return ret;
450}
451
452static ssize_t config_upload_name_show(struct device *dev,
453 struct device_attribute *attr,
454 char *buf)
455{
456 return config_test_show_str(buf, test_fw_config->upload_name);
457}
458static DEVICE_ATTR_RW(config_upload_name);
459
c92316bf
LR
460static ssize_t config_num_requests_store(struct device *dev,
461 struct device_attribute *attr,
462 const char *buf, size_t count)
463{
464 int rc;
465
466 mutex_lock(&test_fw_mutex);
467 if (test_fw_config->reqs) {
468 pr_err("Must call release_all_firmware prior to changing config\n");
469 rc = -EINVAL;
a5e19233 470 mutex_unlock(&test_fw_mutex);
c92316bf
LR
471 goto out;
472 }
473 mutex_unlock(&test_fw_mutex);
474
475 rc = test_dev_config_update_u8(buf, count,
476 &test_fw_config->num_requests);
477
478out:
479 return rc;
480}
481
482static ssize_t config_num_requests_show(struct device *dev,
483 struct device_attribute *attr,
484 char *buf)
485{
486 return test_dev_config_show_u8(buf, test_fw_config->num_requests);
487}
b6b996b6 488static DEVICE_ATTR_RW(config_num_requests);
c92316bf 489
7feebfa4
SB
490static ssize_t config_into_buf_store(struct device *dev,
491 struct device_attribute *attr,
492 const char *buf, size_t count)
493{
494 return test_dev_config_update_bool(buf,
495 count,
496 &test_fw_config->into_buf);
497}
498
499static ssize_t config_into_buf_show(struct device *dev,
500 struct device_attribute *attr,
501 char *buf)
502{
503 return test_dev_config_show_bool(buf, test_fw_config->into_buf);
504}
505static DEVICE_ATTR_RW(config_into_buf);
506
5d90e05c
SB
507static ssize_t config_buf_size_store(struct device *dev,
508 struct device_attribute *attr,
509 const char *buf, size_t count)
510{
511 int rc;
512
513 mutex_lock(&test_fw_mutex);
514 if (test_fw_config->reqs) {
515 pr_err("Must call release_all_firmware prior to changing config\n");
516 rc = -EINVAL;
517 mutex_unlock(&test_fw_mutex);
518 goto out;
519 }
520 mutex_unlock(&test_fw_mutex);
521
522 rc = test_dev_config_update_size_t(buf, count,
523 &test_fw_config->buf_size);
524
525out:
526 return rc;
527}
528
529static ssize_t config_buf_size_show(struct device *dev,
530 struct device_attribute *attr,
531 char *buf)
532{
533 return test_dev_config_show_size_t(buf, test_fw_config->buf_size);
534}
535static DEVICE_ATTR_RW(config_buf_size);
536
537static ssize_t config_file_offset_store(struct device *dev,
538 struct device_attribute *attr,
539 const char *buf, size_t count)
540{
541 int rc;
542
543 mutex_lock(&test_fw_mutex);
544 if (test_fw_config->reqs) {
545 pr_err("Must call release_all_firmware prior to changing config\n");
546 rc = -EINVAL;
547 mutex_unlock(&test_fw_mutex);
548 goto out;
549 }
550 mutex_unlock(&test_fw_mutex);
551
552 rc = test_dev_config_update_size_t(buf, count,
553 &test_fw_config->file_offset);
554
555out:
556 return rc;
557}
558
559static ssize_t config_file_offset_show(struct device *dev,
560 struct device_attribute *attr,
561 char *buf)
562{
563 return test_dev_config_show_size_t(buf, test_fw_config->file_offset);
564}
565static DEVICE_ATTR_RW(config_file_offset);
566
567static ssize_t config_partial_store(struct device *dev,
568 struct device_attribute *attr,
569 const char *buf, size_t count)
570{
571 return test_dev_config_update_bool(buf,
572 count,
573 &test_fw_config->partial);
574}
575
576static ssize_t config_partial_show(struct device *dev,
577 struct device_attribute *attr,
578 char *buf)
579{
580 return test_dev_config_show_bool(buf, test_fw_config->partial);
581}
582static DEVICE_ATTR_RW(config_partial);
583
c92316bf
LR
584static ssize_t config_sync_direct_store(struct device *dev,
585 struct device_attribute *attr,
586 const char *buf, size_t count)
587{
588 int rc = test_dev_config_update_bool(buf, count,
589 &test_fw_config->sync_direct);
590
591 if (rc == count)
592 test_fw_config->req_firmware = test_fw_config->sync_direct ?
593 request_firmware_direct :
594 request_firmware;
595 return rc;
596}
597
598static ssize_t config_sync_direct_show(struct device *dev,
599 struct device_attribute *attr,
600 char *buf)
601{
602 return test_dev_config_show_bool(buf, test_fw_config->sync_direct);
603}
b6b996b6 604static DEVICE_ATTR_RW(config_sync_direct);
c92316bf
LR
605
606static ssize_t config_send_uevent_store(struct device *dev,
607 struct device_attribute *attr,
608 const char *buf, size_t count)
609{
610 return test_dev_config_update_bool(buf, count,
611 &test_fw_config->send_uevent);
612}
613
614static ssize_t config_send_uevent_show(struct device *dev,
615 struct device_attribute *attr,
616 char *buf)
617{
618 return test_dev_config_show_bool(buf, test_fw_config->send_uevent);
619}
b6b996b6 620static DEVICE_ATTR_RW(config_send_uevent);
c92316bf
LR
621
622static ssize_t config_read_fw_idx_store(struct device *dev,
623 struct device_attribute *attr,
624 const char *buf, size_t count)
625{
626 return test_dev_config_update_u8(buf, count,
627 &test_fw_config->read_fw_idx);
628}
629
630static ssize_t config_read_fw_idx_show(struct device *dev,
631 struct device_attribute *attr,
632 char *buf)
633{
634 return test_dev_config_show_u8(buf, test_fw_config->read_fw_idx);
635}
b6b996b6 636static DEVICE_ATTR_RW(config_read_fw_idx);
c92316bf
LR
637
638
0a8adf58
KC
639static ssize_t trigger_request_store(struct device *dev,
640 struct device_attribute *attr,
641 const char *buf, size_t count)
642{
643 int rc;
644 char *name;
645
be4a1326 646 name = kstrndup(buf, count, GFP_KERNEL);
0a8adf58
KC
647 if (!name)
648 return -ENOSPC;
0a8adf58
KC
649
650 pr_info("loading '%s'\n", name);
651
652 mutex_lock(&test_fw_mutex);
653 release_firmware(test_firmware);
654 test_firmware = NULL;
655 rc = request_firmware(&test_firmware, name, dev);
47e0bbb7 656 if (rc) {
0a8adf58 657 pr_info("load of '%s' failed: %d\n", name, rc);
47e0bbb7
BN
658 goto out;
659 }
660 pr_info("loaded: %zu\n", test_firmware->size);
661 rc = count;
662
663out:
0a8adf58
KC
664 mutex_unlock(&test_fw_mutex);
665
666 kfree(name);
667
47e0bbb7 668 return rc;
0a8adf58
KC
669}
670static DEVICE_ATTR_WO(trigger_request);
671
548193cb 672#ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
baaabecf
KC
673extern struct list_head efi_embedded_fw_list;
674extern bool efi_embedded_fw_checked;
675
548193cb
HG
676static ssize_t trigger_request_platform_store(struct device *dev,
677 struct device_attribute *attr,
678 const char *buf, size_t count)
679{
680 static const u8 test_data[] = {
681 0x55, 0xaa, 0x55, 0xaa, 0x01, 0x02, 0x03, 0x04,
682 0x55, 0xaa, 0x55, 0xaa, 0x05, 0x06, 0x07, 0x08,
683 0x55, 0xaa, 0x55, 0xaa, 0x10, 0x20, 0x30, 0x40,
684 0x55, 0xaa, 0x55, 0xaa, 0x50, 0x60, 0x70, 0x80
685 };
686 struct efi_embedded_fw efi_embedded_fw;
687 const struct firmware *firmware = NULL;
baaabecf 688 bool saved_efi_embedded_fw_checked;
548193cb
HG
689 char *name;
690 int rc;
691
692 name = kstrndup(buf, count, GFP_KERNEL);
693 if (!name)
694 return -ENOSPC;
695
696 pr_info("inserting test platform fw '%s'\n", name);
697 efi_embedded_fw.name = name;
698 efi_embedded_fw.data = (void *)test_data;
699 efi_embedded_fw.length = sizeof(test_data);
700 list_add(&efi_embedded_fw.list, &efi_embedded_fw_list);
baaabecf
KC
701 saved_efi_embedded_fw_checked = efi_embedded_fw_checked;
702 efi_embedded_fw_checked = true;
548193cb
HG
703
704 pr_info("loading '%s'\n", name);
705 rc = firmware_request_platform(&firmware, name, dev);
706 if (rc) {
707 pr_info("load of '%s' failed: %d\n", name, rc);
708 goto out;
709 }
710 if (firmware->size != sizeof(test_data) ||
711 memcmp(firmware->data, test_data, sizeof(test_data)) != 0) {
712 pr_info("firmware contents mismatch for '%s'\n", name);
713 rc = -EINVAL;
714 goto out;
715 }
716 pr_info("loaded: %zu\n", firmware->size);
717 rc = count;
718
719out:
baaabecf 720 efi_embedded_fw_checked = saved_efi_embedded_fw_checked;
548193cb
HG
721 release_firmware(firmware);
722 list_del(&efi_embedded_fw.list);
723 kfree(name);
724
725 return rc;
726}
727static DEVICE_ATTR_WO(trigger_request_platform);
728#endif
729
eb910947
BN
730static DECLARE_COMPLETION(async_fw_done);
731
732static void trigger_async_request_cb(const struct firmware *fw, void *context)
733{
734 test_firmware = fw;
735 complete(&async_fw_done);
736}
737
738static ssize_t trigger_async_request_store(struct device *dev,
739 struct device_attribute *attr,
740 const char *buf, size_t count)
741{
742 int rc;
743 char *name;
744
745 name = kstrndup(buf, count, GFP_KERNEL);
746 if (!name)
747 return -ENOSPC;
748
749 pr_info("loading '%s'\n", name);
750
751 mutex_lock(&test_fw_mutex);
752 release_firmware(test_firmware);
753 test_firmware = NULL;
754 rc = request_firmware_nowait(THIS_MODULE, 1, name, dev, GFP_KERNEL,
755 NULL, trigger_async_request_cb);
756 if (rc) {
757 pr_info("async load of '%s' failed: %d\n", name, rc);
758 kfree(name);
759 goto out;
760 }
761 /* Free 'name' ASAP, to test for race conditions */
762 kfree(name);
763
764 wait_for_completion(&async_fw_done);
765
766 if (test_firmware) {
767 pr_info("loaded: %zu\n", test_firmware->size);
768 rc = count;
769 } else {
770 pr_err("failed to async load firmware\n");
7feebfa4 771 rc = -ENOMEM;
eb910947
BN
772 }
773
774out:
775 mutex_unlock(&test_fw_mutex);
776
777 return rc;
778}
779static DEVICE_ATTR_WO(trigger_async_request);
780
061132d2
LR
781static ssize_t trigger_custom_fallback_store(struct device *dev,
782 struct device_attribute *attr,
783 const char *buf, size_t count)
784{
785 int rc;
786 char *name;
787
788 name = kstrndup(buf, count, GFP_KERNEL);
789 if (!name)
790 return -ENOSPC;
791
792 pr_info("loading '%s' using custom fallback mechanism\n", name);
793
794 mutex_lock(&test_fw_mutex);
795 release_firmware(test_firmware);
796 test_firmware = NULL;
0733d839 797 rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOUEVENT, name,
061132d2
LR
798 dev, GFP_KERNEL, NULL,
799 trigger_async_request_cb);
800 if (rc) {
801 pr_info("async load of '%s' failed: %d\n", name, rc);
802 kfree(name);
803 goto out;
804 }
805 /* Free 'name' ASAP, to test for race conditions */
806 kfree(name);
807
808 wait_for_completion(&async_fw_done);
809
810 if (test_firmware) {
811 pr_info("loaded: %zu\n", test_firmware->size);
812 rc = count;
813 } else {
814 pr_err("failed to async load firmware\n");
815 rc = -ENODEV;
816 }
817
818out:
819 mutex_unlock(&test_fw_mutex);
820
821 return rc;
822}
823static DEVICE_ATTR_WO(trigger_custom_fallback);
824
c92316bf
LR
825static int test_fw_run_batch_request(void *data)
826{
827 struct test_batched_req *req = data;
828
829 if (!req) {
830 test_fw_config->test_result = -EINVAL;
831 return -EINVAL;
832 }
833
7feebfa4
SB
834 if (test_fw_config->into_buf) {
835 void *test_buf;
836
837 test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL);
838 if (!test_buf)
839 return -ENOSPC;
840
5d90e05c
SB
841 if (test_fw_config->partial)
842 req->rc = request_partial_firmware_into_buf
843 (&req->fw,
844 req->name,
845 req->dev,
846 test_buf,
847 test_fw_config->buf_size,
848 test_fw_config->file_offset);
849 else
850 req->rc = request_firmware_into_buf
851 (&req->fw,
852 req->name,
853 req->dev,
854 test_buf,
855 test_fw_config->buf_size);
7feebfa4
SB
856 if (!req->fw)
857 kfree(test_buf);
858 } else {
859 req->rc = test_fw_config->req_firmware(&req->fw,
860 req->name,
861 req->dev);
862 }
863
c92316bf
LR
864 if (req->rc) {
865 pr_info("#%u: batched sync load failed: %d\n",
866 req->idx, req->rc);
867 if (!test_fw_config->test_result)
868 test_fw_config->test_result = req->rc;
869 } else if (req->fw) {
870 req->sent = true;
871 pr_info("#%u: batched sync loaded %zu\n",
872 req->idx, req->fw->size);
873 }
874 complete(&req->completion);
875
876 req->task = NULL;
877
878 return 0;
879}
880
881/*
882 * We use a kthread as otherwise the kernel serializes all our sync requests
883 * and we would not be able to mimic batched requests on a sync call. Batched
884 * requests on a sync call can for instance happen on a device driver when
885 * multiple cards are used and firmware loading happens outside of probe.
886 */
887static ssize_t trigger_batched_requests_store(struct device *dev,
888 struct device_attribute *attr,
889 const char *buf, size_t count)
890{
891 struct test_batched_req *req;
892 int rc;
893 u8 i;
894
895 mutex_lock(&test_fw_mutex);
896
fad953ce
KC
897 test_fw_config->reqs =
898 vzalloc(array3_size(sizeof(struct test_batched_req),
899 test_fw_config->num_requests, 2));
c92316bf
LR
900 if (!test_fw_config->reqs) {
901 rc = -ENOMEM;
902 goto out_unlock;
903 }
904
905 pr_info("batched sync firmware loading '%s' %u times\n",
906 test_fw_config->name, test_fw_config->num_requests);
907
908 for (i = 0; i < test_fw_config->num_requests; i++) {
909 req = &test_fw_config->reqs[i];
c92316bf
LR
910 req->fw = NULL;
911 req->idx = i;
912 req->name = test_fw_config->name;
913 req->dev = dev;
914 init_completion(&req->completion);
915 req->task = kthread_run(test_fw_run_batch_request, req,
916 "%s-%u", KBUILD_MODNAME, req->idx);
917 if (!req->task || IS_ERR(req->task)) {
918 pr_err("Setting up thread %u failed\n", req->idx);
919 req->task = NULL;
920 rc = -ENOMEM;
921 goto out_bail;
922 }
923 }
924
925 rc = count;
926
927 /*
928 * We require an explicit release to enable more time and delay of
929 * calling release_firmware() to improve our chances of forcing a
930 * batched request. If we instead called release_firmware() right away
931 * then we might miss on an opportunity of having a successful firmware
932 * request pass on the opportunity to be come a batched request.
933 */
934
935out_bail:
936 for (i = 0; i < test_fw_config->num_requests; i++) {
937 req = &test_fw_config->reqs[i];
938 if (req->task || req->sent)
939 wait_for_completion(&req->completion);
940 }
941
942 /* Override any worker error if we had a general setup error */
943 if (rc < 0)
944 test_fw_config->test_result = rc;
945
946out_unlock:
947 mutex_unlock(&test_fw_mutex);
948
949 return rc;
950}
951static DEVICE_ATTR_WO(trigger_batched_requests);
952
953/*
954 * We wait for each callback to return with the lock held, no need to lock here
955 */
956static void trigger_batched_cb(const struct firmware *fw, void *context)
957{
958 struct test_batched_req *req = context;
959
960 if (!req) {
961 test_fw_config->test_result = -EINVAL;
962 return;
963 }
964
965 /* forces *some* batched requests to queue up */
966 if (!req->idx)
967 ssleep(2);
968
969 req->fw = fw;
970
971 /*
972 * Unfortunately the firmware API gives us nothing other than a null FW
973 * if the firmware was not found on async requests. Best we can do is
974 * just assume -ENOENT. A better API would pass the actual return
975 * value to the callback.
976 */
977 if (!fw && !test_fw_config->test_result)
978 test_fw_config->test_result = -ENOENT;
979
980 complete(&req->completion);
981}
982
983static
984ssize_t trigger_batched_requests_async_store(struct device *dev,
985 struct device_attribute *attr,
986 const char *buf, size_t count)
987{
988 struct test_batched_req *req;
989 bool send_uevent;
990 int rc;
991 u8 i;
992
993 mutex_lock(&test_fw_mutex);
994
fad953ce
KC
995 test_fw_config->reqs =
996 vzalloc(array3_size(sizeof(struct test_batched_req),
997 test_fw_config->num_requests, 2));
c92316bf
LR
998 if (!test_fw_config->reqs) {
999 rc = -ENOMEM;
1000 goto out;
1001 }
1002
1003 pr_info("batched loading '%s' custom fallback mechanism %u times\n",
1004 test_fw_config->name, test_fw_config->num_requests);
1005
0733d839
SG
1006 send_uevent = test_fw_config->send_uevent ? FW_ACTION_UEVENT :
1007 FW_ACTION_NOUEVENT;
c92316bf
LR
1008
1009 for (i = 0; i < test_fw_config->num_requests; i++) {
1010 req = &test_fw_config->reqs[i];
c92316bf
LR
1011 req->name = test_fw_config->name;
1012 req->fw = NULL;
1013 req->idx = i;
1014 init_completion(&req->completion);
1015 rc = request_firmware_nowait(THIS_MODULE, send_uevent,
1016 req->name,
1017 dev, GFP_KERNEL, req,
1018 trigger_batched_cb);
1019 if (rc) {
1020 pr_info("#%u: batched async load failed setup: %d\n",
1021 i, rc);
1022 req->rc = rc;
1023 goto out_bail;
1024 } else
1025 req->sent = true;
1026 }
1027
1028 rc = count;
1029
1030out_bail:
1031
1032 /*
1033 * We require an explicit release to enable more time and delay of
1034 * calling release_firmware() to improve our chances of forcing a
1035 * batched request. If we instead called release_firmware() right away
1036 * then we might miss on an opportunity of having a successful firmware
1037 * request pass on the opportunity to be come a batched request.
1038 */
1039
1040 for (i = 0; i < test_fw_config->num_requests; i++) {
1041 req = &test_fw_config->reqs[i];
1042 if (req->sent)
1043 wait_for_completion(&req->completion);
1044 }
1045
1046 /* Override any worker error if we had a general setup error */
1047 if (rc < 0)
1048 test_fw_config->test_result = rc;
1049
1050out:
1051 mutex_unlock(&test_fw_mutex);
1052
1053 return rc;
1054}
1055static DEVICE_ATTR_WO(trigger_batched_requests_async);
1056
a31ad463
RW
1057static void upload_release(struct test_firmware_upload *tst)
1058{
1059 firmware_upload_unregister(tst->fwl);
1060 kfree(tst->buf);
1061 kfree(tst->name);
1062 kfree(tst);
1063}
1064
1065static void upload_release_all(void)
1066{
1067 struct test_firmware_upload *tst, *tmp;
1068
1069 list_for_each_entry_safe(tst, tmp, &test_upload_list, node) {
1070 list_del(&tst->node);
1071 upload_release(tst);
1072 }
1073 test_fw_config->upload_name = NULL;
1074}
1075
4a4e975b
RW
1076/*
1077 * This table is replicated from .../firmware_loader/sysfs_upload.c
1078 * and needs to be kept in sync.
1079 */
1080static const char * const fw_upload_err_str[] = {
1081 [FW_UPLOAD_ERR_NONE] = "none",
1082 [FW_UPLOAD_ERR_HW_ERROR] = "hw-error",
1083 [FW_UPLOAD_ERR_TIMEOUT] = "timeout",
1084 [FW_UPLOAD_ERR_CANCELED] = "user-abort",
1085 [FW_UPLOAD_ERR_BUSY] = "device-busy",
1086 [FW_UPLOAD_ERR_INVALID_SIZE] = "invalid-file-size",
1087 [FW_UPLOAD_ERR_RW_ERROR] = "read-write-error",
1088 [FW_UPLOAD_ERR_WEAROUT] = "flash-wearout",
1089};
1090
1091static void upload_err_inject_error(struct test_firmware_upload *tst,
1092 const u8 *p, const char *prog)
1093{
1094 enum fw_upload_err err;
1095
1096 for (err = FW_UPLOAD_ERR_NONE + 1; err < FW_UPLOAD_ERR_MAX; err++) {
1097 if (strncmp(p, fw_upload_err_str[err],
1098 strlen(fw_upload_err_str[err])) == 0) {
1099 tst->inject.prog = prog;
1100 tst->inject.err_code = err;
1101 return;
1102 }
1103 }
1104}
1105
1106static void upload_err_inject_prog(struct test_firmware_upload *tst,
1107 const u8 *p)
1108{
1109 static const char * const progs[] = {
1110 "preparing:", "transferring:", "programming:"
1111 };
1112 int i;
1113
1114 for (i = 0; i < ARRAY_SIZE(progs); i++) {
1115 if (strncmp(p, progs[i], strlen(progs[i])) == 0) {
1116 upload_err_inject_error(tst, p + strlen(progs[i]),
1117 progs[i]);
1118 return;
1119 }
1120 }
1121}
1122
1123#define FIVE_MINUTES_MS (5 * 60 * 1000)
1124static enum fw_upload_err
1125fw_upload_wait_on_cancel(struct test_firmware_upload *tst)
1126{
1127 int ms_delay;
1128
1129 for (ms_delay = 0; ms_delay < FIVE_MINUTES_MS; ms_delay += 100) {
1130 msleep(100);
1131 if (tst->cancel_request)
1132 return FW_UPLOAD_ERR_CANCELED;
1133 }
1134 return FW_UPLOAD_ERR_NONE;
1135}
1136
a31ad463
RW
1137static enum fw_upload_err test_fw_upload_prepare(struct fw_upload *fwl,
1138 const u8 *data, u32 size)
1139{
1140 struct test_firmware_upload *tst = fwl->dd_handle;
4a4e975b
RW
1141 enum fw_upload_err ret = FW_UPLOAD_ERR_NONE;
1142 const char *progress = "preparing:";
a31ad463
RW
1143
1144 tst->cancel_request = false;
1145
4a4e975b
RW
1146 if (!size || size > TEST_UPLOAD_MAX_SIZE) {
1147 ret = FW_UPLOAD_ERR_INVALID_SIZE;
1148 goto err_out;
1149 }
1150
1151 if (strncmp(data, "inject:", strlen("inject:")) == 0)
1152 upload_err_inject_prog(tst, data + strlen("inject:"));
a31ad463
RW
1153
1154 memset(tst->buf, 0, TEST_UPLOAD_MAX_SIZE);
1155 tst->size = size;
1156
4a4e975b
RW
1157 if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
1158 strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
1159 return FW_UPLOAD_ERR_NONE;
1160
1161 if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
1162 ret = fw_upload_wait_on_cancel(tst);
1163 else
1164 ret = tst->inject.err_code;
1165
1166err_out:
1167 /*
1168 * The cleanup op only executes if the prepare op succeeds.
1169 * If the prepare op fails, it must do it's own clean-up.
1170 */
1171 tst->inject.err_code = FW_UPLOAD_ERR_NONE;
1172 tst->inject.prog = NULL;
1173
1174 return ret;
a31ad463
RW
1175}
1176
1177static enum fw_upload_err test_fw_upload_write(struct fw_upload *fwl,
1178 const u8 *data, u32 offset,
1179 u32 size, u32 *written)
1180{
1181 struct test_firmware_upload *tst = fwl->dd_handle;
4a4e975b 1182 const char *progress = "transferring:";
a31ad463
RW
1183 u32 blk_size;
1184
1185 if (tst->cancel_request)
1186 return FW_UPLOAD_ERR_CANCELED;
1187
1188 blk_size = min_t(u32, TEST_UPLOAD_BLK_SIZE, size);
1189 memcpy(tst->buf + offset, data + offset, blk_size);
1190
1191 *written = blk_size;
4a4e975b
RW
1192
1193 if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
1194 strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
1195 return FW_UPLOAD_ERR_NONE;
1196
1197 if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
1198 return fw_upload_wait_on_cancel(tst);
1199
1200 return tst->inject.err_code;
a31ad463
RW
1201}
1202
1203static enum fw_upload_err test_fw_upload_complete(struct fw_upload *fwl)
1204{
1205 struct test_firmware_upload *tst = fwl->dd_handle;
4a4e975b 1206 const char *progress = "programming:";
a31ad463
RW
1207
1208 if (tst->cancel_request)
1209 return FW_UPLOAD_ERR_CANCELED;
1210
4a4e975b
RW
1211 if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
1212 strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
1213 return FW_UPLOAD_ERR_NONE;
1214
1215 if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
1216 return fw_upload_wait_on_cancel(tst);
1217
1218 return tst->inject.err_code;
a31ad463
RW
1219}
1220
1221static void test_fw_upload_cancel(struct fw_upload *fwl)
1222{
1223 struct test_firmware_upload *tst = fwl->dd_handle;
1224
1225 tst->cancel_request = true;
1226}
1227
4a4e975b
RW
1228static void test_fw_cleanup(struct fw_upload *fwl)
1229{
1230 struct test_firmware_upload *tst = fwl->dd_handle;
1231
1232 tst->inject.err_code = FW_UPLOAD_ERR_NONE;
1233 tst->inject.prog = NULL;
1234}
1235
a31ad463
RW
1236static const struct fw_upload_ops upload_test_ops = {
1237 .prepare = test_fw_upload_prepare,
1238 .write = test_fw_upload_write,
1239 .poll_complete = test_fw_upload_complete,
1240 .cancel = test_fw_upload_cancel,
4a4e975b 1241 .cleanup = test_fw_cleanup
a31ad463
RW
1242};
1243
1244static ssize_t upload_register_store(struct device *dev,
1245 struct device_attribute *attr,
1246 const char *buf, size_t count)
1247{
1248 struct test_firmware_upload *tst;
1249 struct fw_upload *fwl;
1250 char *name;
1251 int ret;
1252
1253 name = kstrndup(buf, count, GFP_KERNEL);
1254 if (!name)
1255 return -ENOMEM;
1256
1257 mutex_lock(&test_fw_mutex);
1258 tst = upload_lookup_name(name);
1259 if (tst) {
1260 ret = -EEXIST;
1261 goto free_name;
1262 }
1263
1264 tst = kzalloc(sizeof(*tst), GFP_KERNEL);
1265 if (!tst) {
1266 ret = -ENOMEM;
1267 goto free_name;
1268 }
1269
1270 tst->name = name;
1271 tst->buf = kzalloc(TEST_UPLOAD_MAX_SIZE, GFP_KERNEL);
1272 if (!tst->buf) {
1273 ret = -ENOMEM;
1274 goto free_tst;
1275 }
1276
1277 fwl = firmware_upload_register(THIS_MODULE, dev, tst->name,
1278 &upload_test_ops, tst);
1279 if (IS_ERR(fwl)) {
1280 ret = PTR_ERR(fwl);
1281 goto free_buf;
1282 }
1283
1284 tst->fwl = fwl;
1285 list_add_tail(&tst->node, &test_upload_list);
1286 mutex_unlock(&test_fw_mutex);
1287 return count;
1288
1289free_buf:
1290 kfree(tst->buf);
1291
1292free_tst:
1293 kfree(tst);
1294
1295free_name:
1296 mutex_unlock(&test_fw_mutex);
1297 kfree(name);
1298
1299 return ret;
1300}
1301static DEVICE_ATTR_WO(upload_register);
1302
1303static ssize_t upload_unregister_store(struct device *dev,
1304 struct device_attribute *attr,
1305 const char *buf, size_t count)
1306{
1307 struct test_firmware_upload *tst;
1308 int ret = count;
1309
1310 mutex_lock(&test_fw_mutex);
1311 tst = upload_lookup_name(buf);
1312 if (!tst) {
1313 ret = -EINVAL;
1314 goto out;
1315 }
1316
1317 if (test_fw_config->upload_name == tst->name)
1318 test_fw_config->upload_name = NULL;
1319
1320 list_del(&tst->node);
1321 upload_release(tst);
1322
1323out:
1324 mutex_unlock(&test_fw_mutex);
1325 return ret;
1326}
1327static DEVICE_ATTR_WO(upload_unregister);
1328
c92316bf
LR
1329static ssize_t test_result_show(struct device *dev,
1330 struct device_attribute *attr,
1331 char *buf)
1332{
1333 return test_dev_config_show_int(buf, test_fw_config->test_result);
1334}
1335static DEVICE_ATTR_RO(test_result);
1336
1337static ssize_t release_all_firmware_store(struct device *dev,
1338 struct device_attribute *attr,
1339 const char *buf, size_t count)
1340{
1341 test_release_all_firmware();
1342 return count;
1343}
1344static DEVICE_ATTR_WO(release_all_firmware);
1345
1346static ssize_t read_firmware_show(struct device *dev,
1347 struct device_attribute *attr,
1348 char *buf)
1349{
1350 struct test_batched_req *req;
1351 u8 idx;
1352 ssize_t rc = 0;
1353
1354 mutex_lock(&test_fw_mutex);
1355
1356 idx = test_fw_config->read_fw_idx;
1357 if (idx >= test_fw_config->num_requests) {
1358 rc = -ERANGE;
1359 goto out;
1360 }
1361
1362 if (!test_fw_config->reqs) {
1363 rc = -EINVAL;
1364 goto out;
1365 }
1366
1367 req = &test_fw_config->reqs[idx];
1368 if (!req->fw) {
1369 pr_err("#%u: failed to async load firmware\n", idx);
1370 rc = -ENOENT;
1371 goto out;
1372 }
1373
1374 pr_info("#%u: loaded %zu\n", idx, req->fw->size);
1375
1376 if (req->fw->size > PAGE_SIZE) {
1377 pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
1378 rc = -EINVAL;
8bb0a886 1379 goto out;
c92316bf
LR
1380 }
1381 memcpy(buf, req->fw->data, req->fw->size);
1382
1383 rc = req->fw->size;
1384out:
1385 mutex_unlock(&test_fw_mutex);
1386
1387 return rc;
1388}
1389static DEVICE_ATTR_RO(read_firmware);
1390
a31ad463
RW
1391static ssize_t upload_read_show(struct device *dev,
1392 struct device_attribute *attr,
1393 char *buf)
1394{
185b29c6
DC
1395 struct test_firmware_upload *tst = NULL;
1396 struct test_firmware_upload *tst_iter;
a31ad463
RW
1397 int ret = -EINVAL;
1398
1399 if (!test_fw_config->upload_name) {
1400 pr_err("Set config_upload_name before using upload_read\n");
1401 return -EINVAL;
1402 }
1403
1404 mutex_lock(&test_fw_mutex);
185b29c6
DC
1405 list_for_each_entry(tst_iter, &test_upload_list, node)
1406 if (tst_iter->name == test_fw_config->upload_name) {
1407 tst = tst_iter;
a31ad463 1408 break;
185b29c6 1409 }
a31ad463 1410
185b29c6 1411 if (!tst) {
a31ad463
RW
1412 pr_err("Firmware name not found: %s\n",
1413 test_fw_config->upload_name);
1414 goto out;
1415 }
1416
1417 if (tst->size > PAGE_SIZE) {
1418 pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
1419 goto out;
1420 }
1421
1422 memcpy(buf, tst->buf, tst->size);
1423 ret = tst->size;
1424out:
1425 mutex_unlock(&test_fw_mutex);
1426 return ret;
1427}
1428static DEVICE_ATTR_RO(upload_read);
1429
083a93b0
LR
1430#define TEST_FW_DEV_ATTR(name) &dev_attr_##name.attr
1431
1432static struct attribute *test_dev_attrs[] = {
c92316bf
LR
1433 TEST_FW_DEV_ATTR(reset),
1434
1435 TEST_FW_DEV_ATTR(config),
1436 TEST_FW_DEV_ATTR(config_name),
1437 TEST_FW_DEV_ATTR(config_num_requests),
7feebfa4 1438 TEST_FW_DEV_ATTR(config_into_buf),
5d90e05c
SB
1439 TEST_FW_DEV_ATTR(config_buf_size),
1440 TEST_FW_DEV_ATTR(config_file_offset),
1441 TEST_FW_DEV_ATTR(config_partial),
c92316bf
LR
1442 TEST_FW_DEV_ATTR(config_sync_direct),
1443 TEST_FW_DEV_ATTR(config_send_uevent),
1444 TEST_FW_DEV_ATTR(config_read_fw_idx),
a31ad463 1445 TEST_FW_DEV_ATTR(config_upload_name),
c92316bf
LR
1446
1447 /* These don't use the config at all - they could be ported! */
083a93b0
LR
1448 TEST_FW_DEV_ATTR(trigger_request),
1449 TEST_FW_DEV_ATTR(trigger_async_request),
061132d2 1450 TEST_FW_DEV_ATTR(trigger_custom_fallback),
548193cb
HG
1451#ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
1452 TEST_FW_DEV_ATTR(trigger_request_platform),
1453#endif
c92316bf
LR
1454
1455 /* These use the config and can use the test_result */
1456 TEST_FW_DEV_ATTR(trigger_batched_requests),
1457 TEST_FW_DEV_ATTR(trigger_batched_requests_async),
1458
1459 TEST_FW_DEV_ATTR(release_all_firmware),
1460 TEST_FW_DEV_ATTR(test_result),
1461 TEST_FW_DEV_ATTR(read_firmware),
a31ad463
RW
1462 TEST_FW_DEV_ATTR(upload_read),
1463 TEST_FW_DEV_ATTR(upload_register),
1464 TEST_FW_DEV_ATTR(upload_unregister),
083a93b0
LR
1465 NULL,
1466};
1467
1468ATTRIBUTE_GROUPS(test_dev);
1469
67fd553c
LR
1470static struct miscdevice test_fw_misc_device = {
1471 .minor = MISC_DYNAMIC_MINOR,
1472 .name = "test_firmware",
1473 .fops = &test_fw_fops,
083a93b0 1474 .groups = test_dev_groups,
67fd553c
LR
1475};
1476
0a8adf58
KC
1477static int __init test_firmware_init(void)
1478{
1479 int rc;
1480
c92316bf
LR
1481 test_fw_config = kzalloc(sizeof(struct test_config), GFP_KERNEL);
1482 if (!test_fw_config)
1483 return -ENOMEM;
1484
1485 rc = __test_firmware_config_init();
d4fddac5
WW
1486 if (rc) {
1487 kfree(test_fw_config);
1488 pr_err("could not init firmware test config: %d\n", rc);
c92316bf 1489 return rc;
d4fddac5 1490 }
c92316bf 1491
0a8adf58
KC
1492 rc = misc_register(&test_fw_misc_device);
1493 if (rc) {
7610615e 1494 __test_firmware_config_free();
c92316bf 1495 kfree(test_fw_config);
0a8adf58
KC
1496 pr_err("could not register misc device: %d\n", rc);
1497 return rc;
1498 }
eb910947 1499
0a8adf58
KC
1500 pr_warn("interface ready\n");
1501
1502 return 0;
0a8adf58
KC
1503}
1504
1505module_init(test_firmware_init);
1506
1507static void __exit test_firmware_exit(void)
1508{
c92316bf 1509 mutex_lock(&test_fw_mutex);
0a8adf58 1510 release_firmware(test_firmware);
0a8adf58 1511 misc_deregister(&test_fw_misc_device);
a31ad463 1512 upload_release_all();
c92316bf
LR
1513 __test_firmware_config_free();
1514 kfree(test_fw_config);
1515 mutex_unlock(&test_fw_mutex);
1516
0a8adf58
KC
1517 pr_warn("removed interface\n");
1518}
1519
1520module_exit(test_firmware_exit);
1521
1522MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
1523MODULE_LICENSE("GPL");