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