1 // SPDX-License-Identifier: GPL-2.0-only
3 * This module provides an interface to trigger and test firmware loading.
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.
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/printk.h>
16 #include <linux/completion.h>
17 #include <linux/firmware.h>
18 #include <linux/device.h>
20 #include <linux/miscdevice.h>
21 #include <linux/sizes.h>
22 #include <linux/slab.h>
23 #include <linux/uaccess.h>
24 #include <linux/delay.h>
25 #include <linux/kthread.h>
26 #include <linux/vmalloc.h>
27 #include <linux/efi_embedded_fw.h>
29 MODULE_IMPORT_NS(TEST_FIRMWARE
);
31 #define TEST_FIRMWARE_NAME "test-firmware.bin"
32 #define TEST_FIRMWARE_NUM_REQS 4
33 #define TEST_FIRMWARE_BUF_SIZE SZ_1K
35 static DEFINE_MUTEX(test_fw_mutex
);
36 static const struct firmware
*test_firmware
;
38 struct test_batched_req
{
42 const struct firmware
*fw
;
44 struct completion completion
;
45 struct task_struct
*task
;
50 * test_config - represents configuration for the test for different triggers
52 * @name: the name of the firmware file to look for
53 * @into_buf: when the into_buf is used if this is true
54 * request_firmware_into_buf() will be used instead.
55 * @sync_direct: when the sync trigger is used if this is true
56 * request_firmware_direct() will be used instead.
57 * @send_uevent: whether or not to send a uevent for async requests
58 * @num_requests: number of requests to try per test case. This is trigger
60 * @reqs: stores all requests information
61 * @read_fw_idx: index of thread from which we want to read firmware results
62 * from through the read_fw trigger.
63 * @test_result: a test may use this to collect the result from the call
64 * of the request_firmware*() calls used in their tests. In order of
65 * priority we always keep first any setup error. If no setup errors were
66 * found then we move on to the first error encountered while running the
67 * API. Note that for async calls this typically will be a successful
68 * result (0) unless of course you've used bogus parameters, or the system
69 * is out of memory. In the async case the callback is expected to do a
70 * bit more homework to figure out what happened, unfortunately the only
71 * information passed today on error is the fact that no firmware was
72 * found so we can only assume -ENOENT on async calls if the firmware is
75 * Errors you can expect:
79 * 0: success for sync, for async it means request was sent
80 * -EINVAL: invalid parameters or request
81 * -ENOENT: files not found
85 * -ENOMEM: memory pressure on system
86 * -ENODEV: out of number of devices to test
87 * -EINVAL: an unexpected error has occurred
88 * @req_firmware: if @sync_direct is true this is set to
89 * request_firmware_direct(), otherwise request_firmware()
100 * These below don't belong her but we'll move them once we create
101 * a struct fw_test_device and stuff the misc_dev under there later.
103 struct test_batched_req
*reqs
;
105 int (*req_firmware
)(const struct firmware
**fw
, const char *name
,
106 struct device
*device
);
109 static struct test_config
*test_fw_config
;
111 static ssize_t
test_fw_misc_read(struct file
*f
, char __user
*buf
,
112 size_t size
, loff_t
*offset
)
116 mutex_lock(&test_fw_mutex
);
118 rc
= simple_read_from_buffer(buf
, size
, offset
,
120 test_firmware
->size
);
121 mutex_unlock(&test_fw_mutex
);
125 static const struct file_operations test_fw_fops
= {
126 .owner
= THIS_MODULE
,
127 .read
= test_fw_misc_read
,
130 static void __test_release_all_firmware(void)
132 struct test_batched_req
*req
;
135 if (!test_fw_config
->reqs
)
138 for (i
= 0; i
< test_fw_config
->num_requests
; i
++) {
139 req
= &test_fw_config
->reqs
[i
];
141 release_firmware(req
->fw
);
144 vfree(test_fw_config
->reqs
);
145 test_fw_config
->reqs
= NULL
;
148 static void test_release_all_firmware(void)
150 mutex_lock(&test_fw_mutex
);
151 __test_release_all_firmware();
152 mutex_unlock(&test_fw_mutex
);
156 static void __test_firmware_config_free(void)
158 __test_release_all_firmware();
159 kfree_const(test_fw_config
->name
);
160 test_fw_config
->name
= NULL
;
164 * XXX: move to kstrncpy() once merged.
166 * Users should use kfree_const() when freeing these.
168 static int __kstrncpy(char **dst
, const char *name
, size_t count
, gfp_t gfp
)
170 *dst
= kstrndup(name
, count
, gfp
);
176 static int __test_firmware_config_init(void)
180 ret
= __kstrncpy(&test_fw_config
->name
, TEST_FIRMWARE_NAME
,
181 strlen(TEST_FIRMWARE_NAME
), GFP_KERNEL
);
185 test_fw_config
->num_requests
= TEST_FIRMWARE_NUM_REQS
;
186 test_fw_config
->send_uevent
= true;
187 test_fw_config
->into_buf
= false;
188 test_fw_config
->sync_direct
= false;
189 test_fw_config
->req_firmware
= request_firmware
;
190 test_fw_config
->test_result
= 0;
191 test_fw_config
->reqs
= NULL
;
196 __test_firmware_config_free();
200 static ssize_t
reset_store(struct device
*dev
,
201 struct device_attribute
*attr
,
202 const char *buf
, size_t count
)
206 mutex_lock(&test_fw_mutex
);
208 __test_firmware_config_free();
210 ret
= __test_firmware_config_init();
213 pr_err("could not alloc settings for config trigger: %d\n",
222 mutex_unlock(&test_fw_mutex
);
226 static DEVICE_ATTR_WO(reset
);
228 static ssize_t
config_show(struct device
*dev
,
229 struct device_attribute
*attr
,
234 mutex_lock(&test_fw_mutex
);
236 len
+= scnprintf(buf
, PAGE_SIZE
- len
,
237 "Custom trigger configuration for: %s\n",
240 if (test_fw_config
->name
)
241 len
+= scnprintf(buf
+len
, PAGE_SIZE
- len
,
243 test_fw_config
->name
);
245 len
+= scnprintf(buf
+len
, PAGE_SIZE
- len
,
248 len
+= scnprintf(buf
+len
, PAGE_SIZE
- len
,
249 "num_requests:\t%u\n", test_fw_config
->num_requests
);
251 len
+= scnprintf(buf
+len
, PAGE_SIZE
- len
,
252 "send_uevent:\t\t%s\n",
253 test_fw_config
->send_uevent
?
254 "FW_ACTION_HOTPLUG" :
255 "FW_ACTION_NOHOTPLUG");
256 len
+= scnprintf(buf
+len
, PAGE_SIZE
- len
,
258 test_fw_config
->into_buf
? "true" : "false");
259 len
+= scnprintf(buf
+len
, PAGE_SIZE
- len
,
260 "sync_direct:\t\t%s\n",
261 test_fw_config
->sync_direct
? "true" : "false");
262 len
+= scnprintf(buf
+len
, PAGE_SIZE
- len
,
263 "read_fw_idx:\t%u\n", test_fw_config
->read_fw_idx
);
265 mutex_unlock(&test_fw_mutex
);
269 static DEVICE_ATTR_RO(config
);
271 static ssize_t
config_name_store(struct device
*dev
,
272 struct device_attribute
*attr
,
273 const char *buf
, size_t count
)
277 mutex_lock(&test_fw_mutex
);
278 kfree_const(test_fw_config
->name
);
279 ret
= __kstrncpy(&test_fw_config
->name
, buf
, count
, GFP_KERNEL
);
280 mutex_unlock(&test_fw_mutex
);
286 * As per sysfs_kf_seq_show() the buf is max PAGE_SIZE.
288 static ssize_t
config_test_show_str(char *dst
,
293 mutex_lock(&test_fw_mutex
);
294 len
= snprintf(dst
, PAGE_SIZE
, "%s\n", src
);
295 mutex_unlock(&test_fw_mutex
);
300 static int test_dev_config_update_bool(const char *buf
, size_t size
,
305 mutex_lock(&test_fw_mutex
);
306 if (strtobool(buf
, cfg
) < 0)
310 mutex_unlock(&test_fw_mutex
);
315 static ssize_t
test_dev_config_show_bool(char *buf
, bool val
)
317 return snprintf(buf
, PAGE_SIZE
, "%d\n", val
);
320 static ssize_t
test_dev_config_show_int(char *buf
, int val
)
322 return snprintf(buf
, PAGE_SIZE
, "%d\n", val
);
325 static int test_dev_config_update_u8(const char *buf
, size_t size
, u8
*cfg
)
330 ret
= kstrtol(buf
, 10, &new);
337 mutex_lock(&test_fw_mutex
);
339 mutex_unlock(&test_fw_mutex
);
341 /* Always return full write size even if we didn't consume all */
345 static ssize_t
test_dev_config_show_u8(char *buf
, u8 val
)
347 return snprintf(buf
, PAGE_SIZE
, "%u\n", val
);
350 static ssize_t
config_name_show(struct device
*dev
,
351 struct device_attribute
*attr
,
354 return config_test_show_str(buf
, test_fw_config
->name
);
356 static DEVICE_ATTR_RW(config_name
);
358 static ssize_t
config_num_requests_store(struct device
*dev
,
359 struct device_attribute
*attr
,
360 const char *buf
, size_t count
)
364 mutex_lock(&test_fw_mutex
);
365 if (test_fw_config
->reqs
) {
366 pr_err("Must call release_all_firmware prior to changing config\n");
368 mutex_unlock(&test_fw_mutex
);
371 mutex_unlock(&test_fw_mutex
);
373 rc
= test_dev_config_update_u8(buf
, count
,
374 &test_fw_config
->num_requests
);
380 static ssize_t
config_num_requests_show(struct device
*dev
,
381 struct device_attribute
*attr
,
384 return test_dev_config_show_u8(buf
, test_fw_config
->num_requests
);
386 static DEVICE_ATTR_RW(config_num_requests
);
388 static ssize_t
config_into_buf_store(struct device
*dev
,
389 struct device_attribute
*attr
,
390 const char *buf
, size_t count
)
392 return test_dev_config_update_bool(buf
,
394 &test_fw_config
->into_buf
);
397 static ssize_t
config_into_buf_show(struct device
*dev
,
398 struct device_attribute
*attr
,
401 return test_dev_config_show_bool(buf
, test_fw_config
->into_buf
);
403 static DEVICE_ATTR_RW(config_into_buf
);
405 static ssize_t
config_sync_direct_store(struct device
*dev
,
406 struct device_attribute
*attr
,
407 const char *buf
, size_t count
)
409 int rc
= test_dev_config_update_bool(buf
, count
,
410 &test_fw_config
->sync_direct
);
413 test_fw_config
->req_firmware
= test_fw_config
->sync_direct
?
414 request_firmware_direct
:
419 static ssize_t
config_sync_direct_show(struct device
*dev
,
420 struct device_attribute
*attr
,
423 return test_dev_config_show_bool(buf
, test_fw_config
->sync_direct
);
425 static DEVICE_ATTR_RW(config_sync_direct
);
427 static ssize_t
config_send_uevent_store(struct device
*dev
,
428 struct device_attribute
*attr
,
429 const char *buf
, size_t count
)
431 return test_dev_config_update_bool(buf
, count
,
432 &test_fw_config
->send_uevent
);
435 static ssize_t
config_send_uevent_show(struct device
*dev
,
436 struct device_attribute
*attr
,
439 return test_dev_config_show_bool(buf
, test_fw_config
->send_uevent
);
441 static DEVICE_ATTR_RW(config_send_uevent
);
443 static ssize_t
config_read_fw_idx_store(struct device
*dev
,
444 struct device_attribute
*attr
,
445 const char *buf
, size_t count
)
447 return test_dev_config_update_u8(buf
, count
,
448 &test_fw_config
->read_fw_idx
);
451 static ssize_t
config_read_fw_idx_show(struct device
*dev
,
452 struct device_attribute
*attr
,
455 return test_dev_config_show_u8(buf
, test_fw_config
->read_fw_idx
);
457 static DEVICE_ATTR_RW(config_read_fw_idx
);
460 static ssize_t
trigger_request_store(struct device
*dev
,
461 struct device_attribute
*attr
,
462 const char *buf
, size_t count
)
467 name
= kstrndup(buf
, count
, GFP_KERNEL
);
471 pr_info("loading '%s'\n", name
);
473 mutex_lock(&test_fw_mutex
);
474 release_firmware(test_firmware
);
475 test_firmware
= NULL
;
476 rc
= request_firmware(&test_firmware
, name
, dev
);
478 pr_info("load of '%s' failed: %d\n", name
, rc
);
481 pr_info("loaded: %zu\n", test_firmware
->size
);
485 mutex_unlock(&test_fw_mutex
);
491 static DEVICE_ATTR_WO(trigger_request
);
493 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
494 extern struct list_head efi_embedded_fw_list
;
495 extern bool efi_embedded_fw_checked
;
497 static ssize_t
trigger_request_platform_store(struct device
*dev
,
498 struct device_attribute
*attr
,
499 const char *buf
, size_t count
)
501 static const u8 test_data
[] = {
502 0x55, 0xaa, 0x55, 0xaa, 0x01, 0x02, 0x03, 0x04,
503 0x55, 0xaa, 0x55, 0xaa, 0x05, 0x06, 0x07, 0x08,
504 0x55, 0xaa, 0x55, 0xaa, 0x10, 0x20, 0x30, 0x40,
505 0x55, 0xaa, 0x55, 0xaa, 0x50, 0x60, 0x70, 0x80
507 struct efi_embedded_fw efi_embedded_fw
;
508 const struct firmware
*firmware
= NULL
;
509 bool saved_efi_embedded_fw_checked
;
513 name
= kstrndup(buf
, count
, GFP_KERNEL
);
517 pr_info("inserting test platform fw '%s'\n", name
);
518 efi_embedded_fw
.name
= name
;
519 efi_embedded_fw
.data
= (void *)test_data
;
520 efi_embedded_fw
.length
= sizeof(test_data
);
521 list_add(&efi_embedded_fw
.list
, &efi_embedded_fw_list
);
522 saved_efi_embedded_fw_checked
= efi_embedded_fw_checked
;
523 efi_embedded_fw_checked
= true;
525 pr_info("loading '%s'\n", name
);
526 rc
= firmware_request_platform(&firmware
, name
, dev
);
528 pr_info("load of '%s' failed: %d\n", name
, rc
);
531 if (firmware
->size
!= sizeof(test_data
) ||
532 memcmp(firmware
->data
, test_data
, sizeof(test_data
)) != 0) {
533 pr_info("firmware contents mismatch for '%s'\n", name
);
537 pr_info("loaded: %zu\n", firmware
->size
);
541 efi_embedded_fw_checked
= saved_efi_embedded_fw_checked
;
542 release_firmware(firmware
);
543 list_del(&efi_embedded_fw
.list
);
548 static DEVICE_ATTR_WO(trigger_request_platform
);
551 static DECLARE_COMPLETION(async_fw_done
);
553 static void trigger_async_request_cb(const struct firmware
*fw
, void *context
)
556 complete(&async_fw_done
);
559 static ssize_t
trigger_async_request_store(struct device
*dev
,
560 struct device_attribute
*attr
,
561 const char *buf
, size_t count
)
566 name
= kstrndup(buf
, count
, GFP_KERNEL
);
570 pr_info("loading '%s'\n", name
);
572 mutex_lock(&test_fw_mutex
);
573 release_firmware(test_firmware
);
574 test_firmware
= NULL
;
575 rc
= request_firmware_nowait(THIS_MODULE
, 1, name
, dev
, GFP_KERNEL
,
576 NULL
, trigger_async_request_cb
);
578 pr_info("async load of '%s' failed: %d\n", name
, rc
);
582 /* Free 'name' ASAP, to test for race conditions */
585 wait_for_completion(&async_fw_done
);
588 pr_info("loaded: %zu\n", test_firmware
->size
);
591 pr_err("failed to async load firmware\n");
596 mutex_unlock(&test_fw_mutex
);
600 static DEVICE_ATTR_WO(trigger_async_request
);
602 static ssize_t
trigger_custom_fallback_store(struct device
*dev
,
603 struct device_attribute
*attr
,
604 const char *buf
, size_t count
)
609 name
= kstrndup(buf
, count
, GFP_KERNEL
);
613 pr_info("loading '%s' using custom fallback mechanism\n", name
);
615 mutex_lock(&test_fw_mutex
);
616 release_firmware(test_firmware
);
617 test_firmware
= NULL
;
618 rc
= request_firmware_nowait(THIS_MODULE
, FW_ACTION_NOHOTPLUG
, name
,
619 dev
, GFP_KERNEL
, NULL
,
620 trigger_async_request_cb
);
622 pr_info("async load of '%s' failed: %d\n", name
, rc
);
626 /* Free 'name' ASAP, to test for race conditions */
629 wait_for_completion(&async_fw_done
);
632 pr_info("loaded: %zu\n", test_firmware
->size
);
635 pr_err("failed to async load firmware\n");
640 mutex_unlock(&test_fw_mutex
);
644 static DEVICE_ATTR_WO(trigger_custom_fallback
);
646 static int test_fw_run_batch_request(void *data
)
648 struct test_batched_req
*req
= data
;
651 test_fw_config
->test_result
= -EINVAL
;
655 if (test_fw_config
->into_buf
) {
658 test_buf
= kzalloc(TEST_FIRMWARE_BUF_SIZE
, GFP_KERNEL
);
662 req
->rc
= request_firmware_into_buf(&req
->fw
,
666 TEST_FIRMWARE_BUF_SIZE
);
670 req
->rc
= test_fw_config
->req_firmware(&req
->fw
,
676 pr_info("#%u: batched sync load failed: %d\n",
678 if (!test_fw_config
->test_result
)
679 test_fw_config
->test_result
= req
->rc
;
680 } else if (req
->fw
) {
682 pr_info("#%u: batched sync loaded %zu\n",
683 req
->idx
, req
->fw
->size
);
685 complete(&req
->completion
);
693 * We use a kthread as otherwise the kernel serializes all our sync requests
694 * and we would not be able to mimic batched requests on a sync call. Batched
695 * requests on a sync call can for instance happen on a device driver when
696 * multiple cards are used and firmware loading happens outside of probe.
698 static ssize_t
trigger_batched_requests_store(struct device
*dev
,
699 struct device_attribute
*attr
,
700 const char *buf
, size_t count
)
702 struct test_batched_req
*req
;
706 mutex_lock(&test_fw_mutex
);
708 test_fw_config
->reqs
=
709 vzalloc(array3_size(sizeof(struct test_batched_req
),
710 test_fw_config
->num_requests
, 2));
711 if (!test_fw_config
->reqs
) {
716 pr_info("batched sync firmware loading '%s' %u times\n",
717 test_fw_config
->name
, test_fw_config
->num_requests
);
719 for (i
= 0; i
< test_fw_config
->num_requests
; i
++) {
720 req
= &test_fw_config
->reqs
[i
];
723 req
->name
= test_fw_config
->name
;
725 init_completion(&req
->completion
);
726 req
->task
= kthread_run(test_fw_run_batch_request
, req
,
727 "%s-%u", KBUILD_MODNAME
, req
->idx
);
728 if (!req
->task
|| IS_ERR(req
->task
)) {
729 pr_err("Setting up thread %u failed\n", req
->idx
);
739 * We require an explicit release to enable more time and delay of
740 * calling release_firmware() to improve our chances of forcing a
741 * batched request. If we instead called release_firmware() right away
742 * then we might miss on an opportunity of having a successful firmware
743 * request pass on the opportunity to be come a batched request.
747 for (i
= 0; i
< test_fw_config
->num_requests
; i
++) {
748 req
= &test_fw_config
->reqs
[i
];
749 if (req
->task
|| req
->sent
)
750 wait_for_completion(&req
->completion
);
753 /* Override any worker error if we had a general setup error */
755 test_fw_config
->test_result
= rc
;
758 mutex_unlock(&test_fw_mutex
);
762 static DEVICE_ATTR_WO(trigger_batched_requests
);
765 * We wait for each callback to return with the lock held, no need to lock here
767 static void trigger_batched_cb(const struct firmware
*fw
, void *context
)
769 struct test_batched_req
*req
= context
;
772 test_fw_config
->test_result
= -EINVAL
;
776 /* forces *some* batched requests to queue up */
783 * Unfortunately the firmware API gives us nothing other than a null FW
784 * if the firmware was not found on async requests. Best we can do is
785 * just assume -ENOENT. A better API would pass the actual return
786 * value to the callback.
788 if (!fw
&& !test_fw_config
->test_result
)
789 test_fw_config
->test_result
= -ENOENT
;
791 complete(&req
->completion
);
795 ssize_t
trigger_batched_requests_async_store(struct device
*dev
,
796 struct device_attribute
*attr
,
797 const char *buf
, size_t count
)
799 struct test_batched_req
*req
;
804 mutex_lock(&test_fw_mutex
);
806 test_fw_config
->reqs
=
807 vzalloc(array3_size(sizeof(struct test_batched_req
),
808 test_fw_config
->num_requests
, 2));
809 if (!test_fw_config
->reqs
) {
814 pr_info("batched loading '%s' custom fallback mechanism %u times\n",
815 test_fw_config
->name
, test_fw_config
->num_requests
);
817 send_uevent
= test_fw_config
->send_uevent
? FW_ACTION_HOTPLUG
:
820 for (i
= 0; i
< test_fw_config
->num_requests
; i
++) {
821 req
= &test_fw_config
->reqs
[i
];
822 req
->name
= test_fw_config
->name
;
825 init_completion(&req
->completion
);
826 rc
= request_firmware_nowait(THIS_MODULE
, send_uevent
,
828 dev
, GFP_KERNEL
, req
,
831 pr_info("#%u: batched async load failed setup: %d\n",
844 * We require an explicit release to enable more time and delay of
845 * calling release_firmware() to improve our chances of forcing a
846 * batched request. If we instead called release_firmware() right away
847 * then we might miss on an opportunity of having a successful firmware
848 * request pass on the opportunity to be come a batched request.
851 for (i
= 0; i
< test_fw_config
->num_requests
; i
++) {
852 req
= &test_fw_config
->reqs
[i
];
854 wait_for_completion(&req
->completion
);
857 /* Override any worker error if we had a general setup error */
859 test_fw_config
->test_result
= rc
;
862 mutex_unlock(&test_fw_mutex
);
866 static DEVICE_ATTR_WO(trigger_batched_requests_async
);
868 static ssize_t
test_result_show(struct device
*dev
,
869 struct device_attribute
*attr
,
872 return test_dev_config_show_int(buf
, test_fw_config
->test_result
);
874 static DEVICE_ATTR_RO(test_result
);
876 static ssize_t
release_all_firmware_store(struct device
*dev
,
877 struct device_attribute
*attr
,
878 const char *buf
, size_t count
)
880 test_release_all_firmware();
883 static DEVICE_ATTR_WO(release_all_firmware
);
885 static ssize_t
read_firmware_show(struct device
*dev
,
886 struct device_attribute
*attr
,
889 struct test_batched_req
*req
;
893 mutex_lock(&test_fw_mutex
);
895 idx
= test_fw_config
->read_fw_idx
;
896 if (idx
>= test_fw_config
->num_requests
) {
901 if (!test_fw_config
->reqs
) {
906 req
= &test_fw_config
->reqs
[idx
];
908 pr_err("#%u: failed to async load firmware\n", idx
);
913 pr_info("#%u: loaded %zu\n", idx
, req
->fw
->size
);
915 if (req
->fw
->size
> PAGE_SIZE
) {
916 pr_err("Testing interface must use PAGE_SIZE firmware for now\n");
920 memcpy(buf
, req
->fw
->data
, req
->fw
->size
);
924 mutex_unlock(&test_fw_mutex
);
928 static DEVICE_ATTR_RO(read_firmware
);
930 #define TEST_FW_DEV_ATTR(name) &dev_attr_##name.attr
932 static struct attribute
*test_dev_attrs
[] = {
933 TEST_FW_DEV_ATTR(reset
),
935 TEST_FW_DEV_ATTR(config
),
936 TEST_FW_DEV_ATTR(config_name
),
937 TEST_FW_DEV_ATTR(config_num_requests
),
938 TEST_FW_DEV_ATTR(config_into_buf
),
939 TEST_FW_DEV_ATTR(config_sync_direct
),
940 TEST_FW_DEV_ATTR(config_send_uevent
),
941 TEST_FW_DEV_ATTR(config_read_fw_idx
),
943 /* These don't use the config at all - they could be ported! */
944 TEST_FW_DEV_ATTR(trigger_request
),
945 TEST_FW_DEV_ATTR(trigger_async_request
),
946 TEST_FW_DEV_ATTR(trigger_custom_fallback
),
947 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
948 TEST_FW_DEV_ATTR(trigger_request_platform
),
951 /* These use the config and can use the test_result */
952 TEST_FW_DEV_ATTR(trigger_batched_requests
),
953 TEST_FW_DEV_ATTR(trigger_batched_requests_async
),
955 TEST_FW_DEV_ATTR(release_all_firmware
),
956 TEST_FW_DEV_ATTR(test_result
),
957 TEST_FW_DEV_ATTR(read_firmware
),
961 ATTRIBUTE_GROUPS(test_dev
);
963 static struct miscdevice test_fw_misc_device
= {
964 .minor
= MISC_DYNAMIC_MINOR
,
965 .name
= "test_firmware",
966 .fops
= &test_fw_fops
,
967 .groups
= test_dev_groups
,
970 static int __init
test_firmware_init(void)
974 test_fw_config
= kzalloc(sizeof(struct test_config
), GFP_KERNEL
);
978 rc
= __test_firmware_config_init();
980 kfree(test_fw_config
);
981 pr_err("could not init firmware test config: %d\n", rc
);
985 rc
= misc_register(&test_fw_misc_device
);
987 kfree(test_fw_config
);
988 pr_err("could not register misc device: %d\n", rc
);
992 pr_warn("interface ready\n");
997 module_init(test_firmware_init
);
999 static void __exit
test_firmware_exit(void)
1001 mutex_lock(&test_fw_mutex
);
1002 release_firmware(test_firmware
);
1003 misc_deregister(&test_fw_misc_device
);
1004 __test_firmware_config_free();
1005 kfree(test_fw_config
);
1006 mutex_unlock(&test_fw_mutex
);
1008 pr_warn("removed interface\n");
1011 module_exit(test_firmware_exit
);
1013 MODULE_AUTHOR("Kees Cook <keescook@chromium.org>");
1014 MODULE_LICENSE("GPL");