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