Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'driver-core-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core updates from Greg KH:
"Here is the "big" set of driver core patches for 4.17-rc1.

There's really not much here, just a bunch of firmware code
refactoring from Luis as he attempts to wrangle that codebase into
something that is managable, along with a bunch of userspace tests for
it. Other than that, a handful of small bugfixes and reverts of things
that didn't work out.

Full details are in the shortlog, it's not all that much.

All of these have been in linux-next for a while with no reported
issues"

* tag 'driver-core-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (30 commits)
drivers: base: remove check for callback in coredump_store()
mt7601u: use firmware_request_cache() to address cache on reboot
firmware: add firmware_request_cache() to help with cache on reboot
firmware: fix typo on pr_info_once() when ignore_sysfs_fallback is used
firmware: explicitly include vmalloc.h
firmware: ensure the firmware cache is not used on incompatible calls
test_firmware: modify custom fallback tests to use unique files
firmware: add helper to check to see if fw cache is setup
firmware: fix checking for return values for fw_add_devm_name()
rename: _request_firmware_load() fw_load_sysfs_fallback()
test_firmware: test three firmware kernel configs using a proc knob
test_firmware: expand on library with shared helpers
firmware: enable to force disable the fallback mechanism at run time
firmware: enable run time change of forcing fallback loader
firmware: move firmware loader into its own directory
firmware: split firmware fallback functionality into its own file
firmware: move loading timeout under struct firmware_fallback_config
firmware: use helpers for setting up a temporary cache timeout
firmware: simplify CONFIG_FW_LOADER_USER_HELPER_FALLBACK further
drivers: base: add description for .coredump() callback
...

+1370 -894
+1 -1
Documentation/driver-api/firmware/fallback-mechanisms.rst
··· 112 112 fallback mechanism userspace can be informed of the addition of the device by 113 113 relying on kobject uevents. The addition of the device into the device 114 114 hierarchy means the fallback mechanism for firmware loading has been initiated. 115 - For details of implementation refer to _request_firmware_load(), in particular 115 + For details of implementation refer to fw_load_sysfs_fallback(), in particular 116 116 on the use of dev_set_uevent_suppress() and kobject_uevent(). 117 117 118 118 The kernel's kobject uevent mechanism is implemented in lib/kobject_uevent.c,
+14
Documentation/driver-api/firmware/request_firmware.rst
··· 44 44 .. kernel-doc:: drivers/base/firmware_class.c 45 45 :functions: request_firmware_nowait 46 46 47 + Special optimizations on reboot 48 + =============================== 49 + 50 + Some devices have an optimization in place to enable the firmware to be 51 + retained during system reboot. When such optimizations are used the driver 52 + author must ensure the firmware is still available on resume from suspend, 53 + this can be done with firmware_request_cache() insted of requesting for the 54 + firmare to be loaded. 55 + 56 + firmware_request_cache() 57 + ----------------------- 58 + .. kernel-doc:: drivers/base/firmware_class.c 59 + :functions: firmware_request_cache 60 + 47 61 request firmware API expected driver use 48 62 ======================================== 49 63
+1 -1
MAINTAINERS
··· 5524 5524 L: linux-kernel@vger.kernel.org 5525 5525 S: Maintained 5526 5526 F: Documentation/firmware_class/ 5527 - F: drivers/base/firmware*.c 5527 + F: drivers/base/firmware_loader/ 5528 5528 F: include/linux/firmware.h 5529 5529 5530 5530 FLASH ADAPTER DRIVER (IBM Flash Adapter 900GB Full Height PCI Flash Card)
+1 -1
drivers/base/Makefile
··· 13 13 obj-$(CONFIG_HAS_DMA) += dma-mapping.o 14 14 obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o 15 15 obj-$(CONFIG_ISA_BUS_API) += isa.o 16 - obj-$(CONFIG_FW_LOADER) += firmware_class.o 16 + obj-y += firmware_loader/ 17 17 obj-$(CONFIG_NUMA) += node.o 18 18 obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o 19 19 ifeq ($(CONFIG_SYSFS),y)
+6 -6
drivers/base/arch_topology.c
··· 169 169 } 170 170 171 171 #ifdef CONFIG_CPU_FREQ 172 - static cpumask_var_t cpus_to_visit __initdata; 173 - static void __init parsing_done_workfn(struct work_struct *work); 174 - static __initdata DECLARE_WORK(parsing_done_work, parsing_done_workfn); 172 + static cpumask_var_t cpus_to_visit; 173 + static void parsing_done_workfn(struct work_struct *work); 174 + static DECLARE_WORK(parsing_done_work, parsing_done_workfn); 175 175 176 - static int __init 176 + static int 177 177 init_cpu_capacity_callback(struct notifier_block *nb, 178 178 unsigned long val, 179 179 void *data) ··· 209 209 return 0; 210 210 } 211 211 212 - static struct notifier_block init_cpu_capacity_notifier __initdata = { 212 + static struct notifier_block init_cpu_capacity_notifier = { 213 213 .notifier_call = init_cpu_capacity_callback, 214 214 }; 215 215 ··· 242 242 } 243 243 core_initcall(register_cpufreq_notifier); 244 244 245 - static void __init parsing_done_workfn(struct work_struct *work) 245 + static void parsing_done_workfn(struct work_struct *work) 246 246 { 247 247 cpufreq_unregister_notifier(&init_cpu_capacity_notifier, 248 248 CPUFREQ_POLICY_NOTIFIER);
+3 -1
drivers/base/cpu.c
··· 382 382 if (cpu->hotpluggable) 383 383 cpu->dev.groups = hotplugable_cpu_attr_groups; 384 384 error = device_register(&cpu->dev); 385 - if (error) 385 + if (error) { 386 + put_device(&cpu->dev); 386 387 return error; 388 + } 387 389 388 390 per_cpu(cpu_sys_devices, num) = &cpu->dev; 389 391 register_cpu_under_node(num, cpu_to_node(num));
+1 -2
drivers/base/dd.c
··· 292 292 const char *buf, size_t count) 293 293 { 294 294 device_lock(dev); 295 - if (dev->driver->coredump) 296 - dev->driver->coredump(dev); 295 + dev->driver->coredump(dev); 297 296 device_unlock(dev); 298 297 299 298 return count;
+68 -765
drivers/base/firmware_class.c drivers/base/firmware_loader/main.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * firmware_class.c - Multi purpose firmware loading support 3 + * main.c - Multi purpose firmware loading support 4 4 * 5 5 * Copyright (c) 2003 Manuel Estrada Sainz 6 6 * ··· 36 36 37 37 #include <generated/utsrelease.h> 38 38 39 - #include "base.h" 39 + #include "../base.h" 40 + #include "firmware.h" 41 + #include "fallback.h" 40 42 41 43 MODULE_AUTHOR("Manuel Estrada Sainz"); 42 44 MODULE_DESCRIPTION("Multi purpose firmware loading support"); 43 45 MODULE_LICENSE("GPL"); 44 - 45 - enum fw_status { 46 - FW_STATUS_UNKNOWN, 47 - FW_STATUS_LOADING, 48 - FW_STATUS_DONE, 49 - FW_STATUS_ABORTED, 50 - }; 51 - 52 - /* 53 - * Concurrent request_firmware() for the same firmware need to be 54 - * serialized. struct fw_state is simple state machine which hold the 55 - * state of the firmware loading. 56 - */ 57 - struct fw_state { 58 - struct completion completion; 59 - enum fw_status status; 60 - }; 61 - 62 - /* firmware behavior options */ 63 - #define FW_OPT_UEVENT (1U << 0) 64 - #define FW_OPT_NOWAIT (1U << 1) 65 - #define FW_OPT_USERHELPER (1U << 2) 66 - #define FW_OPT_NO_WARN (1U << 3) 67 - #define FW_OPT_NOCACHE (1U << 4) 68 - #define FW_OPT_NOFALLBACK (1U << 5) 69 46 70 47 struct firmware_cache { 71 48 /* firmware_buf instance will be added into the below list */ ··· 66 89 #endif 67 90 }; 68 91 69 - struct fw_priv { 70 - struct kref ref; 71 - struct list_head list; 72 - struct firmware_cache *fwc; 73 - struct fw_state fw_st; 74 - void *data; 75 - size_t size; 76 - size_t allocated_size; 77 - #ifdef CONFIG_FW_LOADER_USER_HELPER 78 - bool is_paged_buf; 79 - bool need_uevent; 80 - struct page **pages; 81 - int nr_pages; 82 - int page_array_size; 83 - struct list_head pending_list; 84 - #endif 85 - const char *fw_name; 86 - }; 87 - 88 92 struct fw_cache_entry { 89 93 struct list_head list; 90 94 const char *name; ··· 86 128 87 129 /* fw_lock could be moved to 'struct fw_sysfs' but since it is just 88 130 * guarding for corner cases a global lock should be OK */ 89 - static DEFINE_MUTEX(fw_lock); 131 + DEFINE_MUTEX(fw_lock); 90 132 91 133 static struct firmware_cache fw_cache; 92 134 ··· 149 191 } 150 192 #endif 151 193 152 - static int loading_timeout = 60; /* In seconds */ 153 - 154 - static inline long firmware_loading_timeout(void) 155 - { 156 - return loading_timeout > 0 ? loading_timeout * HZ : MAX_JIFFY_OFFSET; 157 - } 158 - 159 194 static void fw_state_init(struct fw_priv *fw_priv) 160 195 { 161 196 struct fw_state *fw_st = &fw_priv->fw_st; ··· 157 206 fw_st->status = FW_STATUS_UNKNOWN; 158 207 } 159 208 160 - static int __fw_state_wait_common(struct fw_priv *fw_priv, long timeout) 161 - { 162 - struct fw_state *fw_st = &fw_priv->fw_st; 163 - long ret; 164 - 165 - ret = wait_for_completion_killable_timeout(&fw_st->completion, timeout); 166 - if (ret != 0 && fw_st->status == FW_STATUS_ABORTED) 167 - return -ENOENT; 168 - if (!ret) 169 - return -ETIMEDOUT; 170 - 171 - return ret < 0 ? ret : 0; 172 - } 173 - 174 - static void __fw_state_set(struct fw_priv *fw_priv, 175 - enum fw_status status) 176 - { 177 - struct fw_state *fw_st = &fw_priv->fw_st; 178 - 179 - WRITE_ONCE(fw_st->status, status); 180 - 181 - if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) 182 - complete_all(&fw_st->completion); 183 - } 184 - 185 - static inline void fw_state_start(struct fw_priv *fw_priv) 186 - { 187 - __fw_state_set(fw_priv, FW_STATUS_LOADING); 188 - } 189 - 190 - static inline void fw_state_done(struct fw_priv *fw_priv) 191 - { 192 - __fw_state_set(fw_priv, FW_STATUS_DONE); 193 - } 194 - 195 - static inline void fw_state_aborted(struct fw_priv *fw_priv) 196 - { 197 - __fw_state_set(fw_priv, FW_STATUS_ABORTED); 198 - } 199 - 200 209 static inline int fw_state_wait(struct fw_priv *fw_priv) 201 210 { 202 211 return __fw_state_wait_common(fw_priv, MAX_SCHEDULE_TIMEOUT); 203 212 } 204 - 205 - static bool __fw_state_check(struct fw_priv *fw_priv, 206 - enum fw_status status) 207 - { 208 - struct fw_state *fw_st = &fw_priv->fw_st; 209 - 210 - return fw_st->status == status; 211 - } 212 - 213 - static inline bool fw_state_is_aborted(struct fw_priv *fw_priv) 214 - { 215 - return __fw_state_check(fw_priv, FW_STATUS_ABORTED); 216 - } 217 - 218 - #ifdef CONFIG_FW_LOADER_USER_HELPER 219 - 220 - static inline bool fw_sysfs_done(struct fw_priv *fw_priv) 221 - { 222 - return __fw_state_check(fw_priv, FW_STATUS_DONE); 223 - } 224 - 225 - static inline bool fw_sysfs_loading(struct fw_priv *fw_priv) 226 - { 227 - return __fw_state_check(fw_priv, FW_STATUS_LOADING); 228 - } 229 - 230 - static inline int fw_sysfs_wait_timeout(struct fw_priv *fw_priv, long timeout) 231 - { 232 - return __fw_state_wait_common(fw_priv, timeout); 233 - } 234 - 235 - #endif /* CONFIG_FW_LOADER_USER_HELPER */ 236 213 237 214 static int fw_cache_piggyback_on_request(const char *name); 238 215 ··· 396 517 return fwn; 397 518 } 398 519 399 - /* add firmware name into devres list */ 400 - static int fw_add_devm_name(struct device *dev, const char *name) 520 + static bool fw_cache_is_setup(struct device *dev, const char *name) 401 521 { 402 522 struct fw_name_devm *fwn; 403 523 404 524 fwn = fw_find_devm_name(dev, name); 405 525 if (fwn) 406 - return 1; 526 + return true; 527 + 528 + return false; 529 + } 530 + 531 + /* add firmware name into devres list */ 532 + static int fw_add_devm_name(struct device *dev, const char *name) 533 + { 534 + struct fw_name_devm *fwn; 535 + 536 + if (fw_cache_is_setup(dev, name)) 537 + return 0; 407 538 408 539 fwn = devres_alloc(fw_name_devm_release, sizeof(struct fw_name_devm), 409 540 GFP_KERNEL); ··· 431 542 return 0; 432 543 } 433 544 #else 545 + static bool fw_cache_is_setup(struct device *dev, const char *name) 546 + { 547 + return false; 548 + } 549 + 434 550 static int fw_add_devm_name(struct device *dev, const char *name) 435 551 { 436 552 return 0; 437 553 } 438 554 #endif 439 555 440 - static int assign_fw(struct firmware *fw, struct device *device, 441 - unsigned int opt_flags) 556 + int assign_fw(struct firmware *fw, struct device *device, 557 + unsigned int opt_flags) 442 558 { 443 559 struct fw_priv *fw_priv = fw->priv; 560 + int ret; 444 561 445 562 mutex_lock(&fw_lock); 446 563 if (!fw_priv->size || fw_state_is_aborted(fw_priv)) { ··· 463 568 */ 464 569 /* don't cache firmware handled without uevent */ 465 570 if (device && (opt_flags & FW_OPT_UEVENT) && 466 - !(opt_flags & FW_OPT_NOCACHE)) 467 - fw_add_devm_name(device, fw_priv->fw_name); 571 + !(opt_flags & FW_OPT_NOCACHE)) { 572 + ret = fw_add_devm_name(device, fw_priv->fw_name); 573 + if (ret) { 574 + mutex_unlock(&fw_lock); 575 + return ret; 576 + } 577 + } 468 578 469 579 /* 470 580 * After caching firmware image is started, let it piggyback ··· 486 586 mutex_unlock(&fw_lock); 487 587 return 0; 488 588 } 489 - 490 - /* 491 - * user-mode helper code 492 - */ 493 - #ifdef CONFIG_FW_LOADER_USER_HELPER 494 - struct fw_sysfs { 495 - bool nowait; 496 - struct device dev; 497 - struct fw_priv *fw_priv; 498 - struct firmware *fw; 499 - }; 500 - 501 - static struct fw_sysfs *to_fw_sysfs(struct device *dev) 502 - { 503 - return container_of(dev, struct fw_sysfs, dev); 504 - } 505 - 506 - static void __fw_load_abort(struct fw_priv *fw_priv) 507 - { 508 - /* 509 - * There is a small window in which user can write to 'loading' 510 - * between loading done and disappearance of 'loading' 511 - */ 512 - if (fw_sysfs_done(fw_priv)) 513 - return; 514 - 515 - list_del_init(&fw_priv->pending_list); 516 - fw_state_aborted(fw_priv); 517 - } 518 - 519 - static void fw_load_abort(struct fw_sysfs *fw_sysfs) 520 - { 521 - struct fw_priv *fw_priv = fw_sysfs->fw_priv; 522 - 523 - __fw_load_abort(fw_priv); 524 - } 525 - 526 - static LIST_HEAD(pending_fw_head); 527 - 528 - static void kill_pending_fw_fallback_reqs(bool only_kill_custom) 529 - { 530 - struct fw_priv *fw_priv; 531 - struct fw_priv *next; 532 - 533 - mutex_lock(&fw_lock); 534 - list_for_each_entry_safe(fw_priv, next, &pending_fw_head, 535 - pending_list) { 536 - if (!fw_priv->need_uevent || !only_kill_custom) 537 - __fw_load_abort(fw_priv); 538 - } 539 - mutex_unlock(&fw_lock); 540 - } 541 - 542 - static ssize_t timeout_show(struct class *class, struct class_attribute *attr, 543 - char *buf) 544 - { 545 - return sprintf(buf, "%d\n", loading_timeout); 546 - } 547 - 548 - /** 549 - * firmware_timeout_store - set number of seconds to wait for firmware 550 - * @class: device class pointer 551 - * @attr: device attribute pointer 552 - * @buf: buffer to scan for timeout value 553 - * @count: number of bytes in @buf 554 - * 555 - * Sets the number of seconds to wait for the firmware. Once 556 - * this expires an error will be returned to the driver and no 557 - * firmware will be provided. 558 - * 559 - * Note: zero means 'wait forever'. 560 - **/ 561 - static ssize_t timeout_store(struct class *class, struct class_attribute *attr, 562 - const char *buf, size_t count) 563 - { 564 - loading_timeout = simple_strtol(buf, NULL, 10); 565 - if (loading_timeout < 0) 566 - loading_timeout = 0; 567 - 568 - return count; 569 - } 570 - static CLASS_ATTR_RW(timeout); 571 - 572 - static struct attribute *firmware_class_attrs[] = { 573 - &class_attr_timeout.attr, 574 - NULL, 575 - }; 576 - ATTRIBUTE_GROUPS(firmware_class); 577 - 578 - static void fw_dev_release(struct device *dev) 579 - { 580 - struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 581 - 582 - kfree(fw_sysfs); 583 - } 584 - 585 - static int do_firmware_uevent(struct fw_sysfs *fw_sysfs, struct kobj_uevent_env *env) 586 - { 587 - if (add_uevent_var(env, "FIRMWARE=%s", fw_sysfs->fw_priv->fw_name)) 588 - return -ENOMEM; 589 - if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout)) 590 - return -ENOMEM; 591 - if (add_uevent_var(env, "ASYNC=%d", fw_sysfs->nowait)) 592 - return -ENOMEM; 593 - 594 - return 0; 595 - } 596 - 597 - static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) 598 - { 599 - struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 600 - int err = 0; 601 - 602 - mutex_lock(&fw_lock); 603 - if (fw_sysfs->fw_priv) 604 - err = do_firmware_uevent(fw_sysfs, env); 605 - mutex_unlock(&fw_lock); 606 - return err; 607 - } 608 - 609 - static struct class firmware_class = { 610 - .name = "firmware", 611 - .class_groups = firmware_class_groups, 612 - .dev_uevent = firmware_uevent, 613 - .dev_release = fw_dev_release, 614 - }; 615 - 616 - static inline int register_sysfs_loader(void) 617 - { 618 - return class_register(&firmware_class); 619 - } 620 - 621 - static inline void unregister_sysfs_loader(void) 622 - { 623 - class_unregister(&firmware_class); 624 - } 625 - 626 - static ssize_t firmware_loading_show(struct device *dev, 627 - struct device_attribute *attr, char *buf) 628 - { 629 - struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 630 - int loading = 0; 631 - 632 - mutex_lock(&fw_lock); 633 - if (fw_sysfs->fw_priv) 634 - loading = fw_sysfs_loading(fw_sysfs->fw_priv); 635 - mutex_unlock(&fw_lock); 636 - 637 - return sprintf(buf, "%d\n", loading); 638 - } 639 - 640 - /* Some architectures don't have PAGE_KERNEL_RO */ 641 - #ifndef PAGE_KERNEL_RO 642 - #define PAGE_KERNEL_RO PAGE_KERNEL 643 - #endif 644 - 645 - /* one pages buffer should be mapped/unmapped only once */ 646 - static int map_fw_priv_pages(struct fw_priv *fw_priv) 647 - { 648 - if (!fw_priv->is_paged_buf) 649 - return 0; 650 - 651 - vunmap(fw_priv->data); 652 - fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0, 653 - PAGE_KERNEL_RO); 654 - if (!fw_priv->data) 655 - return -ENOMEM; 656 - return 0; 657 - } 658 - 659 - /** 660 - * firmware_loading_store - set value in the 'loading' control file 661 - * @dev: device pointer 662 - * @attr: device attribute pointer 663 - * @buf: buffer to scan for loading control value 664 - * @count: number of bytes in @buf 665 - * 666 - * The relevant values are: 667 - * 668 - * 1: Start a load, discarding any previous partial load. 669 - * 0: Conclude the load and hand the data to the driver code. 670 - * -1: Conclude the load with an error and discard any written data. 671 - **/ 672 - static ssize_t firmware_loading_store(struct device *dev, 673 - struct device_attribute *attr, 674 - const char *buf, size_t count) 675 - { 676 - struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 677 - struct fw_priv *fw_priv; 678 - ssize_t written = count; 679 - int loading = simple_strtol(buf, NULL, 10); 680 - int i; 681 - 682 - mutex_lock(&fw_lock); 683 - fw_priv = fw_sysfs->fw_priv; 684 - if (fw_state_is_aborted(fw_priv)) 685 - goto out; 686 - 687 - switch (loading) { 688 - case 1: 689 - /* discarding any previous partial load */ 690 - if (!fw_sysfs_done(fw_priv)) { 691 - for (i = 0; i < fw_priv->nr_pages; i++) 692 - __free_page(fw_priv->pages[i]); 693 - vfree(fw_priv->pages); 694 - fw_priv->pages = NULL; 695 - fw_priv->page_array_size = 0; 696 - fw_priv->nr_pages = 0; 697 - fw_state_start(fw_priv); 698 - } 699 - break; 700 - case 0: 701 - if (fw_sysfs_loading(fw_priv)) { 702 - int rc; 703 - 704 - /* 705 - * Several loading requests may be pending on 706 - * one same firmware buf, so let all requests 707 - * see the mapped 'buf->data' once the loading 708 - * is completed. 709 - * */ 710 - rc = map_fw_priv_pages(fw_priv); 711 - if (rc) 712 - dev_err(dev, "%s: map pages failed\n", 713 - __func__); 714 - else 715 - rc = security_kernel_post_read_file(NULL, 716 - fw_priv->data, fw_priv->size, 717 - READING_FIRMWARE); 718 - 719 - /* 720 - * Same logic as fw_load_abort, only the DONE bit 721 - * is ignored and we set ABORT only on failure. 722 - */ 723 - list_del_init(&fw_priv->pending_list); 724 - if (rc) { 725 - fw_state_aborted(fw_priv); 726 - written = rc; 727 - } else { 728 - fw_state_done(fw_priv); 729 - } 730 - break; 731 - } 732 - /* fallthrough */ 733 - default: 734 - dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading); 735 - /* fallthrough */ 736 - case -1: 737 - fw_load_abort(fw_sysfs); 738 - break; 739 - } 740 - out: 741 - mutex_unlock(&fw_lock); 742 - return written; 743 - } 744 - 745 - static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); 746 - 747 - static void firmware_rw_data(struct fw_priv *fw_priv, char *buffer, 748 - loff_t offset, size_t count, bool read) 749 - { 750 - if (read) 751 - memcpy(buffer, fw_priv->data + offset, count); 752 - else 753 - memcpy(fw_priv->data + offset, buffer, count); 754 - } 755 - 756 - static void firmware_rw(struct fw_priv *fw_priv, char *buffer, 757 - loff_t offset, size_t count, bool read) 758 - { 759 - while (count) { 760 - void *page_data; 761 - int page_nr = offset >> PAGE_SHIFT; 762 - int page_ofs = offset & (PAGE_SIZE-1); 763 - int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count); 764 - 765 - page_data = kmap(fw_priv->pages[page_nr]); 766 - 767 - if (read) 768 - memcpy(buffer, page_data + page_ofs, page_cnt); 769 - else 770 - memcpy(page_data + page_ofs, buffer, page_cnt); 771 - 772 - kunmap(fw_priv->pages[page_nr]); 773 - buffer += page_cnt; 774 - offset += page_cnt; 775 - count -= page_cnt; 776 - } 777 - } 778 - 779 - static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, 780 - struct bin_attribute *bin_attr, 781 - char *buffer, loff_t offset, size_t count) 782 - { 783 - struct device *dev = kobj_to_dev(kobj); 784 - struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 785 - struct fw_priv *fw_priv; 786 - ssize_t ret_count; 787 - 788 - mutex_lock(&fw_lock); 789 - fw_priv = fw_sysfs->fw_priv; 790 - if (!fw_priv || fw_sysfs_done(fw_priv)) { 791 - ret_count = -ENODEV; 792 - goto out; 793 - } 794 - if (offset > fw_priv->size) { 795 - ret_count = 0; 796 - goto out; 797 - } 798 - if (count > fw_priv->size - offset) 799 - count = fw_priv->size - offset; 800 - 801 - ret_count = count; 802 - 803 - if (fw_priv->data) 804 - firmware_rw_data(fw_priv, buffer, offset, count, true); 805 - else 806 - firmware_rw(fw_priv, buffer, offset, count, true); 807 - 808 - out: 809 - mutex_unlock(&fw_lock); 810 - return ret_count; 811 - } 812 - 813 - static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size) 814 - { 815 - struct fw_priv *fw_priv= fw_sysfs->fw_priv; 816 - int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT; 817 - 818 - /* If the array of pages is too small, grow it... */ 819 - if (fw_priv->page_array_size < pages_needed) { 820 - int new_array_size = max(pages_needed, 821 - fw_priv->page_array_size * 2); 822 - struct page **new_pages; 823 - 824 - new_pages = vmalloc(new_array_size * sizeof(void *)); 825 - if (!new_pages) { 826 - fw_load_abort(fw_sysfs); 827 - return -ENOMEM; 828 - } 829 - memcpy(new_pages, fw_priv->pages, 830 - fw_priv->page_array_size * sizeof(void *)); 831 - memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * 832 - (new_array_size - fw_priv->page_array_size)); 833 - vfree(fw_priv->pages); 834 - fw_priv->pages = new_pages; 835 - fw_priv->page_array_size = new_array_size; 836 - } 837 - 838 - while (fw_priv->nr_pages < pages_needed) { 839 - fw_priv->pages[fw_priv->nr_pages] = 840 - alloc_page(GFP_KERNEL | __GFP_HIGHMEM); 841 - 842 - if (!fw_priv->pages[fw_priv->nr_pages]) { 843 - fw_load_abort(fw_sysfs); 844 - return -ENOMEM; 845 - } 846 - fw_priv->nr_pages++; 847 - } 848 - return 0; 849 - } 850 - 851 - /** 852 - * firmware_data_write - write method for firmware 853 - * @filp: open sysfs file 854 - * @kobj: kobject for the device 855 - * @bin_attr: bin_attr structure 856 - * @buffer: buffer being written 857 - * @offset: buffer offset for write in total data store area 858 - * @count: buffer size 859 - * 860 - * Data written to the 'data' attribute will be later handed to 861 - * the driver as a firmware image. 862 - **/ 863 - static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, 864 - struct bin_attribute *bin_attr, 865 - char *buffer, loff_t offset, size_t count) 866 - { 867 - struct device *dev = kobj_to_dev(kobj); 868 - struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 869 - struct fw_priv *fw_priv; 870 - ssize_t retval; 871 - 872 - if (!capable(CAP_SYS_RAWIO)) 873 - return -EPERM; 874 - 875 - mutex_lock(&fw_lock); 876 - fw_priv = fw_sysfs->fw_priv; 877 - if (!fw_priv || fw_sysfs_done(fw_priv)) { 878 - retval = -ENODEV; 879 - goto out; 880 - } 881 - 882 - if (fw_priv->data) { 883 - if (offset + count > fw_priv->allocated_size) { 884 - retval = -ENOMEM; 885 - goto out; 886 - } 887 - firmware_rw_data(fw_priv, buffer, offset, count, false); 888 - retval = count; 889 - } else { 890 - retval = fw_realloc_pages(fw_sysfs, offset + count); 891 - if (retval) 892 - goto out; 893 - 894 - retval = count; 895 - firmware_rw(fw_priv, buffer, offset, count, false); 896 - } 897 - 898 - fw_priv->size = max_t(size_t, offset + count, fw_priv->size); 899 - out: 900 - mutex_unlock(&fw_lock); 901 - return retval; 902 - } 903 - 904 - static struct bin_attribute firmware_attr_data = { 905 - .attr = { .name = "data", .mode = 0644 }, 906 - .size = 0, 907 - .read = firmware_data_read, 908 - .write = firmware_data_write, 909 - }; 910 - 911 - static struct attribute *fw_dev_attrs[] = { 912 - &dev_attr_loading.attr, 913 - NULL 914 - }; 915 - 916 - static struct bin_attribute *fw_dev_bin_attrs[] = { 917 - &firmware_attr_data, 918 - NULL 919 - }; 920 - 921 - static const struct attribute_group fw_dev_attr_group = { 922 - .attrs = fw_dev_attrs, 923 - .bin_attrs = fw_dev_bin_attrs, 924 - }; 925 - 926 - static const struct attribute_group *fw_dev_attr_groups[] = { 927 - &fw_dev_attr_group, 928 - NULL 929 - }; 930 - 931 - static struct fw_sysfs * 932 - fw_create_instance(struct firmware *firmware, const char *fw_name, 933 - struct device *device, unsigned int opt_flags) 934 - { 935 - struct fw_sysfs *fw_sysfs; 936 - struct device *f_dev; 937 - 938 - fw_sysfs = kzalloc(sizeof(*fw_sysfs), GFP_KERNEL); 939 - if (!fw_sysfs) { 940 - fw_sysfs = ERR_PTR(-ENOMEM); 941 - goto exit; 942 - } 943 - 944 - fw_sysfs->nowait = !!(opt_flags & FW_OPT_NOWAIT); 945 - fw_sysfs->fw = firmware; 946 - f_dev = &fw_sysfs->dev; 947 - 948 - device_initialize(f_dev); 949 - dev_set_name(f_dev, "%s", fw_name); 950 - f_dev->parent = device; 951 - f_dev->class = &firmware_class; 952 - f_dev->groups = fw_dev_attr_groups; 953 - exit: 954 - return fw_sysfs; 955 - } 956 - 957 - /* load a firmware via user helper */ 958 - static int _request_firmware_load(struct fw_sysfs *fw_sysfs, 959 - unsigned int opt_flags, long timeout) 960 - { 961 - int retval = 0; 962 - struct device *f_dev = &fw_sysfs->dev; 963 - struct fw_priv *fw_priv = fw_sysfs->fw_priv; 964 - 965 - /* fall back on userspace loading */ 966 - if (!fw_priv->data) 967 - fw_priv->is_paged_buf = true; 968 - 969 - dev_set_uevent_suppress(f_dev, true); 970 - 971 - retval = device_add(f_dev); 972 - if (retval) { 973 - dev_err(f_dev, "%s: device_register failed\n", __func__); 974 - goto err_put_dev; 975 - } 976 - 977 - mutex_lock(&fw_lock); 978 - list_add(&fw_priv->pending_list, &pending_fw_head); 979 - mutex_unlock(&fw_lock); 980 - 981 - if (opt_flags & FW_OPT_UEVENT) { 982 - fw_priv->need_uevent = true; 983 - dev_set_uevent_suppress(f_dev, false); 984 - dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_name); 985 - kobject_uevent(&fw_sysfs->dev.kobj, KOBJ_ADD); 986 - } else { 987 - timeout = MAX_JIFFY_OFFSET; 988 - } 989 - 990 - retval = fw_sysfs_wait_timeout(fw_priv, timeout); 991 - if (retval < 0) { 992 - mutex_lock(&fw_lock); 993 - fw_load_abort(fw_sysfs); 994 - mutex_unlock(&fw_lock); 995 - } 996 - 997 - if (fw_state_is_aborted(fw_priv)) { 998 - if (retval == -ERESTARTSYS) 999 - retval = -EINTR; 1000 - else 1001 - retval = -EAGAIN; 1002 - } else if (fw_priv->is_paged_buf && !fw_priv->data) 1003 - retval = -ENOMEM; 1004 - 1005 - device_del(f_dev); 1006 - err_put_dev: 1007 - put_device(f_dev); 1008 - return retval; 1009 - } 1010 - 1011 - static int fw_load_from_user_helper(struct firmware *firmware, 1012 - const char *name, struct device *device, 1013 - unsigned int opt_flags) 1014 - { 1015 - struct fw_sysfs *fw_sysfs; 1016 - long timeout; 1017 - int ret; 1018 - 1019 - timeout = firmware_loading_timeout(); 1020 - if (opt_flags & FW_OPT_NOWAIT) { 1021 - timeout = usermodehelper_read_lock_wait(timeout); 1022 - if (!timeout) { 1023 - dev_dbg(device, "firmware: %s loading timed out\n", 1024 - name); 1025 - return -EBUSY; 1026 - } 1027 - } else { 1028 - ret = usermodehelper_read_trylock(); 1029 - if (WARN_ON(ret)) { 1030 - dev_err(device, "firmware: %s will not be loaded\n", 1031 - name); 1032 - return ret; 1033 - } 1034 - } 1035 - 1036 - fw_sysfs = fw_create_instance(firmware, name, device, opt_flags); 1037 - if (IS_ERR(fw_sysfs)) { 1038 - ret = PTR_ERR(fw_sysfs); 1039 - goto out_unlock; 1040 - } 1041 - 1042 - fw_sysfs->fw_priv = firmware->priv; 1043 - ret = _request_firmware_load(fw_sysfs, opt_flags, timeout); 1044 - 1045 - if (!ret) 1046 - ret = assign_fw(firmware, device, opt_flags); 1047 - 1048 - out_unlock: 1049 - usermodehelper_read_unlock(); 1050 - 1051 - return ret; 1052 - } 1053 - 1054 - #ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK 1055 - static bool fw_force_sysfs_fallback(unsigned int opt_flags) 1056 - { 1057 - return true; 1058 - } 1059 - #else 1060 - static bool fw_force_sysfs_fallback(unsigned int opt_flags) 1061 - { 1062 - if (!(opt_flags & FW_OPT_USERHELPER)) 1063 - return false; 1064 - return true; 1065 - } 1066 - #endif 1067 - 1068 - static bool fw_run_sysfs_fallback(unsigned int opt_flags) 1069 - { 1070 - if ((opt_flags & FW_OPT_NOFALLBACK)) 1071 - return false; 1072 - 1073 - return fw_force_sysfs_fallback(opt_flags); 1074 - } 1075 - 1076 - static int fw_sysfs_fallback(struct firmware *fw, const char *name, 1077 - struct device *device, 1078 - unsigned int opt_flags, 1079 - int ret) 1080 - { 1081 - if (!fw_run_sysfs_fallback(opt_flags)) 1082 - return ret; 1083 - 1084 - dev_warn(device, "Falling back to user helper\n"); 1085 - return fw_load_from_user_helper(fw, name, device, opt_flags); 1086 - } 1087 - #else /* CONFIG_FW_LOADER_USER_HELPER */ 1088 - static int fw_sysfs_fallback(struct firmware *fw, const char *name, 1089 - struct device *device, 1090 - unsigned int opt_flags, 1091 - int ret) 1092 - { 1093 - /* Keep carrying over the same error */ 1094 - return ret; 1095 - } 1096 - 1097 - static inline void kill_pending_fw_fallback_reqs(bool only_kill_custom) { } 1098 - 1099 - static inline int register_sysfs_loader(void) 1100 - { 1101 - return 0; 1102 - } 1103 - 1104 - static inline void unregister_sysfs_loader(void) 1105 - { 1106 - } 1107 - 1108 - #endif /* CONFIG_FW_LOADER_USER_HELPER */ 1109 589 1110 590 /* prepare firmware and firmware_buf structs; 1111 591 * return 0 if a firmware is already assigned, 1 if need to load one, ··· 657 1377 EXPORT_SYMBOL_GPL(request_firmware_direct); 658 1378 659 1379 /** 1380 + * firmware_request_cache: - cache firmware for suspend so resume can use it 1381 + * @name: name of firmware file 1382 + * @device: device for which firmware should be cached for 1383 + * 1384 + * There are some devices with an optimization that enables the device to not 1385 + * require loading firmware on system reboot. This optimization may still 1386 + * require the firmware present on resume from suspend. This routine can be 1387 + * used to ensure the firmware is present on resume from suspend in these 1388 + * situations. This helper is not compatible with drivers which use 1389 + * request_firmware_into_buf() or request_firmware_nowait() with no uevent set. 1390 + **/ 1391 + int firmware_request_cache(struct device *device, const char *name) 1392 + { 1393 + int ret; 1394 + 1395 + mutex_lock(&fw_lock); 1396 + ret = fw_add_devm_name(device, name); 1397 + mutex_unlock(&fw_lock); 1398 + 1399 + return ret; 1400 + } 1401 + EXPORT_SYMBOL_GPL(firmware_request_cache); 1402 + 1403 + /** 660 1404 * request_firmware_into_buf - load firmware into a previously allocated buffer 661 1405 * @firmware_p: pointer to firmware image 662 1406 * @name: name of firmware file ··· 700 1396 struct device *device, void *buf, size_t size) 701 1397 { 702 1398 int ret; 1399 + 1400 + if (fw_cache_is_setup(device, name)) 1401 + return -EOPNOTSUPP; 703 1402 704 1403 __module_get(THIS_MODULE); 705 1404 ret = _request_firmware(firmware_p, name, device, buf, size, ··· 800 1493 fw_work->cont = cont; 801 1494 fw_work->opt_flags = FW_OPT_NOWAIT | 802 1495 (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER); 1496 + 1497 + if (!uevent && fw_cache_is_setup(device, name)) { 1498 + kfree_const(fw_work->name); 1499 + kfree(fw_work); 1500 + return -EOPNOTSUPP; 1501 + } 803 1502 804 1503 if (!try_module_get(module)) { 805 1504 kfree_const(fw_work->name); ··· 1054 1741 static void device_cache_fw_images(void) 1055 1742 { 1056 1743 struct firmware_cache *fwc = &fw_cache; 1057 - int old_timeout; 1058 1744 DEFINE_WAIT(wait); 1059 1745 1060 1746 pr_debug("%s\n", __func__); ··· 1061 1749 /* cancel uncache work */ 1062 1750 cancel_delayed_work_sync(&fwc->work); 1063 1751 1064 - /* 1065 - * use small loading timeout for caching devices' firmware 1066 - * because all these firmware images have been loaded 1067 - * successfully at lease once, also system is ready for 1068 - * completing firmware loading now. The maximum size of 1069 - * firmware in current distributions is about 2M bytes, 1070 - * so 10 secs should be enough. 1071 - */ 1072 - old_timeout = loading_timeout; 1073 - loading_timeout = 10; 1752 + fw_fallback_set_cache_timeout(); 1074 1753 1075 1754 mutex_lock(&fw_lock); 1076 1755 fwc->state = FW_LOADER_START_CACHE; ··· 1071 1768 /* wait for completion of caching firmware for all devices */ 1072 1769 async_synchronize_full_domain(&fw_cache_domain); 1073 1770 1074 - loading_timeout = old_timeout; 1771 + fw_fallback_set_default_timeout(); 1075 1772 } 1076 1773 1077 1774 /**
+7
drivers/base/firmware_loader/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # Makefile for the Linux firmware loader 3 + 4 + obj-y := fallback_table.o 5 + obj-$(CONFIG_FW_LOADER) += firmware_class.o 6 + firmware_class-objs := main.o 7 + firmware_class-$(CONFIG_FW_LOADER_USER_HELPER) += fallback.o
+675
drivers/base/firmware_loader/fallback.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/types.h> 4 + #include <linux/kconfig.h> 5 + #include <linux/list.h> 6 + #include <linux/slab.h> 7 + #include <linux/security.h> 8 + #include <linux/highmem.h> 9 + #include <linux/umh.h> 10 + #include <linux/sysctl.h> 11 + #include <linux/vmalloc.h> 12 + 13 + #include "fallback.h" 14 + #include "firmware.h" 15 + 16 + /* 17 + * firmware fallback mechanism 18 + */ 19 + 20 + extern struct firmware_fallback_config fw_fallback_config; 21 + 22 + /* These getters are vetted to use int properly */ 23 + static inline int __firmware_loading_timeout(void) 24 + { 25 + return fw_fallback_config.loading_timeout; 26 + } 27 + 28 + /* These setters are vetted to use int properly */ 29 + static void __fw_fallback_set_timeout(int timeout) 30 + { 31 + fw_fallback_config.loading_timeout = timeout; 32 + } 33 + 34 + /* 35 + * use small loading timeout for caching devices' firmware because all these 36 + * firmware images have been loaded successfully at lease once, also system is 37 + * ready for completing firmware loading now. The maximum size of firmware in 38 + * current distributions is about 2M bytes, so 10 secs should be enough. 39 + */ 40 + void fw_fallback_set_cache_timeout(void) 41 + { 42 + fw_fallback_config.old_timeout = __firmware_loading_timeout(); 43 + __fw_fallback_set_timeout(10); 44 + } 45 + 46 + /* Restores the timeout to the value last configured during normal operation */ 47 + void fw_fallback_set_default_timeout(void) 48 + { 49 + __fw_fallback_set_timeout(fw_fallback_config.old_timeout); 50 + } 51 + 52 + static long firmware_loading_timeout(void) 53 + { 54 + return __firmware_loading_timeout() > 0 ? 55 + __firmware_loading_timeout() * HZ : MAX_JIFFY_OFFSET; 56 + } 57 + 58 + static inline bool fw_sysfs_done(struct fw_priv *fw_priv) 59 + { 60 + return __fw_state_check(fw_priv, FW_STATUS_DONE); 61 + } 62 + 63 + static inline bool fw_sysfs_loading(struct fw_priv *fw_priv) 64 + { 65 + return __fw_state_check(fw_priv, FW_STATUS_LOADING); 66 + } 67 + 68 + static inline int fw_sysfs_wait_timeout(struct fw_priv *fw_priv, long timeout) 69 + { 70 + return __fw_state_wait_common(fw_priv, timeout); 71 + } 72 + 73 + struct fw_sysfs { 74 + bool nowait; 75 + struct device dev; 76 + struct fw_priv *fw_priv; 77 + struct firmware *fw; 78 + }; 79 + 80 + static struct fw_sysfs *to_fw_sysfs(struct device *dev) 81 + { 82 + return container_of(dev, struct fw_sysfs, dev); 83 + } 84 + 85 + static void __fw_load_abort(struct fw_priv *fw_priv) 86 + { 87 + /* 88 + * There is a small window in which user can write to 'loading' 89 + * between loading done and disappearance of 'loading' 90 + */ 91 + if (fw_sysfs_done(fw_priv)) 92 + return; 93 + 94 + list_del_init(&fw_priv->pending_list); 95 + fw_state_aborted(fw_priv); 96 + } 97 + 98 + static void fw_load_abort(struct fw_sysfs *fw_sysfs) 99 + { 100 + struct fw_priv *fw_priv = fw_sysfs->fw_priv; 101 + 102 + __fw_load_abort(fw_priv); 103 + } 104 + 105 + static LIST_HEAD(pending_fw_head); 106 + 107 + void kill_pending_fw_fallback_reqs(bool only_kill_custom) 108 + { 109 + struct fw_priv *fw_priv; 110 + struct fw_priv *next; 111 + 112 + mutex_lock(&fw_lock); 113 + list_for_each_entry_safe(fw_priv, next, &pending_fw_head, 114 + pending_list) { 115 + if (!fw_priv->need_uevent || !only_kill_custom) 116 + __fw_load_abort(fw_priv); 117 + } 118 + mutex_unlock(&fw_lock); 119 + } 120 + 121 + static ssize_t timeout_show(struct class *class, struct class_attribute *attr, 122 + char *buf) 123 + { 124 + return sprintf(buf, "%d\n", __firmware_loading_timeout()); 125 + } 126 + 127 + /** 128 + * firmware_timeout_store - set number of seconds to wait for firmware 129 + * @class: device class pointer 130 + * @attr: device attribute pointer 131 + * @buf: buffer to scan for timeout value 132 + * @count: number of bytes in @buf 133 + * 134 + * Sets the number of seconds to wait for the firmware. Once 135 + * this expires an error will be returned to the driver and no 136 + * firmware will be provided. 137 + * 138 + * Note: zero means 'wait forever'. 139 + **/ 140 + static ssize_t timeout_store(struct class *class, struct class_attribute *attr, 141 + const char *buf, size_t count) 142 + { 143 + int tmp_loading_timeout = simple_strtol(buf, NULL, 10); 144 + 145 + if (tmp_loading_timeout < 0) 146 + tmp_loading_timeout = 0; 147 + 148 + __fw_fallback_set_timeout(tmp_loading_timeout); 149 + 150 + return count; 151 + } 152 + static CLASS_ATTR_RW(timeout); 153 + 154 + static struct attribute *firmware_class_attrs[] = { 155 + &class_attr_timeout.attr, 156 + NULL, 157 + }; 158 + ATTRIBUTE_GROUPS(firmware_class); 159 + 160 + static void fw_dev_release(struct device *dev) 161 + { 162 + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 163 + 164 + kfree(fw_sysfs); 165 + } 166 + 167 + static int do_firmware_uevent(struct fw_sysfs *fw_sysfs, struct kobj_uevent_env *env) 168 + { 169 + if (add_uevent_var(env, "FIRMWARE=%s", fw_sysfs->fw_priv->fw_name)) 170 + return -ENOMEM; 171 + if (add_uevent_var(env, "TIMEOUT=%i", __firmware_loading_timeout())) 172 + return -ENOMEM; 173 + if (add_uevent_var(env, "ASYNC=%d", fw_sysfs->nowait)) 174 + return -ENOMEM; 175 + 176 + return 0; 177 + } 178 + 179 + static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) 180 + { 181 + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 182 + int err = 0; 183 + 184 + mutex_lock(&fw_lock); 185 + if (fw_sysfs->fw_priv) 186 + err = do_firmware_uevent(fw_sysfs, env); 187 + mutex_unlock(&fw_lock); 188 + return err; 189 + } 190 + 191 + static struct class firmware_class = { 192 + .name = "firmware", 193 + .class_groups = firmware_class_groups, 194 + .dev_uevent = firmware_uevent, 195 + .dev_release = fw_dev_release, 196 + }; 197 + 198 + int register_sysfs_loader(void) 199 + { 200 + return class_register(&firmware_class); 201 + } 202 + 203 + void unregister_sysfs_loader(void) 204 + { 205 + class_unregister(&firmware_class); 206 + } 207 + 208 + static ssize_t firmware_loading_show(struct device *dev, 209 + struct device_attribute *attr, char *buf) 210 + { 211 + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 212 + int loading = 0; 213 + 214 + mutex_lock(&fw_lock); 215 + if (fw_sysfs->fw_priv) 216 + loading = fw_sysfs_loading(fw_sysfs->fw_priv); 217 + mutex_unlock(&fw_lock); 218 + 219 + return sprintf(buf, "%d\n", loading); 220 + } 221 + 222 + /* Some architectures don't have PAGE_KERNEL_RO */ 223 + #ifndef PAGE_KERNEL_RO 224 + #define PAGE_KERNEL_RO PAGE_KERNEL 225 + #endif 226 + 227 + /* one pages buffer should be mapped/unmapped only once */ 228 + static int map_fw_priv_pages(struct fw_priv *fw_priv) 229 + { 230 + if (!fw_priv->is_paged_buf) 231 + return 0; 232 + 233 + vunmap(fw_priv->data); 234 + fw_priv->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0, 235 + PAGE_KERNEL_RO); 236 + if (!fw_priv->data) 237 + return -ENOMEM; 238 + return 0; 239 + } 240 + 241 + /** 242 + * firmware_loading_store - set value in the 'loading' control file 243 + * @dev: device pointer 244 + * @attr: device attribute pointer 245 + * @buf: buffer to scan for loading control value 246 + * @count: number of bytes in @buf 247 + * 248 + * The relevant values are: 249 + * 250 + * 1: Start a load, discarding any previous partial load. 251 + * 0: Conclude the load and hand the data to the driver code. 252 + * -1: Conclude the load with an error and discard any written data. 253 + **/ 254 + static ssize_t firmware_loading_store(struct device *dev, 255 + struct device_attribute *attr, 256 + const char *buf, size_t count) 257 + { 258 + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 259 + struct fw_priv *fw_priv; 260 + ssize_t written = count; 261 + int loading = simple_strtol(buf, NULL, 10); 262 + int i; 263 + 264 + mutex_lock(&fw_lock); 265 + fw_priv = fw_sysfs->fw_priv; 266 + if (fw_state_is_aborted(fw_priv)) 267 + goto out; 268 + 269 + switch (loading) { 270 + case 1: 271 + /* discarding any previous partial load */ 272 + if (!fw_sysfs_done(fw_priv)) { 273 + for (i = 0; i < fw_priv->nr_pages; i++) 274 + __free_page(fw_priv->pages[i]); 275 + vfree(fw_priv->pages); 276 + fw_priv->pages = NULL; 277 + fw_priv->page_array_size = 0; 278 + fw_priv->nr_pages = 0; 279 + fw_state_start(fw_priv); 280 + } 281 + break; 282 + case 0: 283 + if (fw_sysfs_loading(fw_priv)) { 284 + int rc; 285 + 286 + /* 287 + * Several loading requests may be pending on 288 + * one same firmware buf, so let all requests 289 + * see the mapped 'buf->data' once the loading 290 + * is completed. 291 + * */ 292 + rc = map_fw_priv_pages(fw_priv); 293 + if (rc) 294 + dev_err(dev, "%s: map pages failed\n", 295 + __func__); 296 + else 297 + rc = security_kernel_post_read_file(NULL, 298 + fw_priv->data, fw_priv->size, 299 + READING_FIRMWARE); 300 + 301 + /* 302 + * Same logic as fw_load_abort, only the DONE bit 303 + * is ignored and we set ABORT only on failure. 304 + */ 305 + list_del_init(&fw_priv->pending_list); 306 + if (rc) { 307 + fw_state_aborted(fw_priv); 308 + written = rc; 309 + } else { 310 + fw_state_done(fw_priv); 311 + } 312 + break; 313 + } 314 + /* fallthrough */ 315 + default: 316 + dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading); 317 + /* fallthrough */ 318 + case -1: 319 + fw_load_abort(fw_sysfs); 320 + break; 321 + } 322 + out: 323 + mutex_unlock(&fw_lock); 324 + return written; 325 + } 326 + 327 + static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); 328 + 329 + static void firmware_rw_data(struct fw_priv *fw_priv, char *buffer, 330 + loff_t offset, size_t count, bool read) 331 + { 332 + if (read) 333 + memcpy(buffer, fw_priv->data + offset, count); 334 + else 335 + memcpy(fw_priv->data + offset, buffer, count); 336 + } 337 + 338 + static void firmware_rw(struct fw_priv *fw_priv, char *buffer, 339 + loff_t offset, size_t count, bool read) 340 + { 341 + while (count) { 342 + void *page_data; 343 + int page_nr = offset >> PAGE_SHIFT; 344 + int page_ofs = offset & (PAGE_SIZE-1); 345 + int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count); 346 + 347 + page_data = kmap(fw_priv->pages[page_nr]); 348 + 349 + if (read) 350 + memcpy(buffer, page_data + page_ofs, page_cnt); 351 + else 352 + memcpy(page_data + page_ofs, buffer, page_cnt); 353 + 354 + kunmap(fw_priv->pages[page_nr]); 355 + buffer += page_cnt; 356 + offset += page_cnt; 357 + count -= page_cnt; 358 + } 359 + } 360 + 361 + static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, 362 + struct bin_attribute *bin_attr, 363 + char *buffer, loff_t offset, size_t count) 364 + { 365 + struct device *dev = kobj_to_dev(kobj); 366 + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 367 + struct fw_priv *fw_priv; 368 + ssize_t ret_count; 369 + 370 + mutex_lock(&fw_lock); 371 + fw_priv = fw_sysfs->fw_priv; 372 + if (!fw_priv || fw_sysfs_done(fw_priv)) { 373 + ret_count = -ENODEV; 374 + goto out; 375 + } 376 + if (offset > fw_priv->size) { 377 + ret_count = 0; 378 + goto out; 379 + } 380 + if (count > fw_priv->size - offset) 381 + count = fw_priv->size - offset; 382 + 383 + ret_count = count; 384 + 385 + if (fw_priv->data) 386 + firmware_rw_data(fw_priv, buffer, offset, count, true); 387 + else 388 + firmware_rw(fw_priv, buffer, offset, count, true); 389 + 390 + out: 391 + mutex_unlock(&fw_lock); 392 + return ret_count; 393 + } 394 + 395 + static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size) 396 + { 397 + struct fw_priv *fw_priv= fw_sysfs->fw_priv; 398 + int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT; 399 + 400 + /* If the array of pages is too small, grow it... */ 401 + if (fw_priv->page_array_size < pages_needed) { 402 + int new_array_size = max(pages_needed, 403 + fw_priv->page_array_size * 2); 404 + struct page **new_pages; 405 + 406 + new_pages = vmalloc(new_array_size * sizeof(void *)); 407 + if (!new_pages) { 408 + fw_load_abort(fw_sysfs); 409 + return -ENOMEM; 410 + } 411 + memcpy(new_pages, fw_priv->pages, 412 + fw_priv->page_array_size * sizeof(void *)); 413 + memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * 414 + (new_array_size - fw_priv->page_array_size)); 415 + vfree(fw_priv->pages); 416 + fw_priv->pages = new_pages; 417 + fw_priv->page_array_size = new_array_size; 418 + } 419 + 420 + while (fw_priv->nr_pages < pages_needed) { 421 + fw_priv->pages[fw_priv->nr_pages] = 422 + alloc_page(GFP_KERNEL | __GFP_HIGHMEM); 423 + 424 + if (!fw_priv->pages[fw_priv->nr_pages]) { 425 + fw_load_abort(fw_sysfs); 426 + return -ENOMEM; 427 + } 428 + fw_priv->nr_pages++; 429 + } 430 + return 0; 431 + } 432 + 433 + /** 434 + * firmware_data_write - write method for firmware 435 + * @filp: open sysfs file 436 + * @kobj: kobject for the device 437 + * @bin_attr: bin_attr structure 438 + * @buffer: buffer being written 439 + * @offset: buffer offset for write in total data store area 440 + * @count: buffer size 441 + * 442 + * Data written to the 'data' attribute will be later handed to 443 + * the driver as a firmware image. 444 + **/ 445 + static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, 446 + struct bin_attribute *bin_attr, 447 + char *buffer, loff_t offset, size_t count) 448 + { 449 + struct device *dev = kobj_to_dev(kobj); 450 + struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev); 451 + struct fw_priv *fw_priv; 452 + ssize_t retval; 453 + 454 + if (!capable(CAP_SYS_RAWIO)) 455 + return -EPERM; 456 + 457 + mutex_lock(&fw_lock); 458 + fw_priv = fw_sysfs->fw_priv; 459 + if (!fw_priv || fw_sysfs_done(fw_priv)) { 460 + retval = -ENODEV; 461 + goto out; 462 + } 463 + 464 + if (fw_priv->data) { 465 + if (offset + count > fw_priv->allocated_size) { 466 + retval = -ENOMEM; 467 + goto out; 468 + } 469 + firmware_rw_data(fw_priv, buffer, offset, count, false); 470 + retval = count; 471 + } else { 472 + retval = fw_realloc_pages(fw_sysfs, offset + count); 473 + if (retval) 474 + goto out; 475 + 476 + retval = count; 477 + firmware_rw(fw_priv, buffer, offset, count, false); 478 + } 479 + 480 + fw_priv->size = max_t(size_t, offset + count, fw_priv->size); 481 + out: 482 + mutex_unlock(&fw_lock); 483 + return retval; 484 + } 485 + 486 + static struct bin_attribute firmware_attr_data = { 487 + .attr = { .name = "data", .mode = 0644 }, 488 + .size = 0, 489 + .read = firmware_data_read, 490 + .write = firmware_data_write, 491 + }; 492 + 493 + static struct attribute *fw_dev_attrs[] = { 494 + &dev_attr_loading.attr, 495 + NULL 496 + }; 497 + 498 + static struct bin_attribute *fw_dev_bin_attrs[] = { 499 + &firmware_attr_data, 500 + NULL 501 + }; 502 + 503 + static const struct attribute_group fw_dev_attr_group = { 504 + .attrs = fw_dev_attrs, 505 + .bin_attrs = fw_dev_bin_attrs, 506 + }; 507 + 508 + static const struct attribute_group *fw_dev_attr_groups[] = { 509 + &fw_dev_attr_group, 510 + NULL 511 + }; 512 + 513 + static struct fw_sysfs * 514 + fw_create_instance(struct firmware *firmware, const char *fw_name, 515 + struct device *device, unsigned int opt_flags) 516 + { 517 + struct fw_sysfs *fw_sysfs; 518 + struct device *f_dev; 519 + 520 + fw_sysfs = kzalloc(sizeof(*fw_sysfs), GFP_KERNEL); 521 + if (!fw_sysfs) { 522 + fw_sysfs = ERR_PTR(-ENOMEM); 523 + goto exit; 524 + } 525 + 526 + fw_sysfs->nowait = !!(opt_flags & FW_OPT_NOWAIT); 527 + fw_sysfs->fw = firmware; 528 + f_dev = &fw_sysfs->dev; 529 + 530 + device_initialize(f_dev); 531 + dev_set_name(f_dev, "%s", fw_name); 532 + f_dev->parent = device; 533 + f_dev->class = &firmware_class; 534 + f_dev->groups = fw_dev_attr_groups; 535 + exit: 536 + return fw_sysfs; 537 + } 538 + 539 + /** 540 + * fw_load_sysfs_fallback - load a firmware via the syfs fallback mechanism 541 + * @fw_sysfs: firmware syfs information for the firmware to load 542 + * @opt_flags: flags of options, FW_OPT_* 543 + * @timeout: timeout to wait for the load 544 + * 545 + * In charge of constructing a sysfs fallback interface for firmware loading. 546 + **/ 547 + static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, 548 + unsigned int opt_flags, long timeout) 549 + { 550 + int retval = 0; 551 + struct device *f_dev = &fw_sysfs->dev; 552 + struct fw_priv *fw_priv = fw_sysfs->fw_priv; 553 + 554 + /* fall back on userspace loading */ 555 + if (!fw_priv->data) 556 + fw_priv->is_paged_buf = true; 557 + 558 + dev_set_uevent_suppress(f_dev, true); 559 + 560 + retval = device_add(f_dev); 561 + if (retval) { 562 + dev_err(f_dev, "%s: device_register failed\n", __func__); 563 + goto err_put_dev; 564 + } 565 + 566 + mutex_lock(&fw_lock); 567 + list_add(&fw_priv->pending_list, &pending_fw_head); 568 + mutex_unlock(&fw_lock); 569 + 570 + if (opt_flags & FW_OPT_UEVENT) { 571 + fw_priv->need_uevent = true; 572 + dev_set_uevent_suppress(f_dev, false); 573 + dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_name); 574 + kobject_uevent(&fw_sysfs->dev.kobj, KOBJ_ADD); 575 + } else { 576 + timeout = MAX_JIFFY_OFFSET; 577 + } 578 + 579 + retval = fw_sysfs_wait_timeout(fw_priv, timeout); 580 + if (retval < 0) { 581 + mutex_lock(&fw_lock); 582 + fw_load_abort(fw_sysfs); 583 + mutex_unlock(&fw_lock); 584 + } 585 + 586 + if (fw_state_is_aborted(fw_priv)) { 587 + if (retval == -ERESTARTSYS) 588 + retval = -EINTR; 589 + else 590 + retval = -EAGAIN; 591 + } else if (fw_priv->is_paged_buf && !fw_priv->data) 592 + retval = -ENOMEM; 593 + 594 + device_del(f_dev); 595 + err_put_dev: 596 + put_device(f_dev); 597 + return retval; 598 + } 599 + 600 + static int fw_load_from_user_helper(struct firmware *firmware, 601 + const char *name, struct device *device, 602 + unsigned int opt_flags) 603 + { 604 + struct fw_sysfs *fw_sysfs; 605 + long timeout; 606 + int ret; 607 + 608 + timeout = firmware_loading_timeout(); 609 + if (opt_flags & FW_OPT_NOWAIT) { 610 + timeout = usermodehelper_read_lock_wait(timeout); 611 + if (!timeout) { 612 + dev_dbg(device, "firmware: %s loading timed out\n", 613 + name); 614 + return -EBUSY; 615 + } 616 + } else { 617 + ret = usermodehelper_read_trylock(); 618 + if (WARN_ON(ret)) { 619 + dev_err(device, "firmware: %s will not be loaded\n", 620 + name); 621 + return ret; 622 + } 623 + } 624 + 625 + fw_sysfs = fw_create_instance(firmware, name, device, opt_flags); 626 + if (IS_ERR(fw_sysfs)) { 627 + ret = PTR_ERR(fw_sysfs); 628 + goto out_unlock; 629 + } 630 + 631 + fw_sysfs->fw_priv = firmware->priv; 632 + ret = fw_load_sysfs_fallback(fw_sysfs, opt_flags, timeout); 633 + 634 + if (!ret) 635 + ret = assign_fw(firmware, device, opt_flags); 636 + 637 + out_unlock: 638 + usermodehelper_read_unlock(); 639 + 640 + return ret; 641 + } 642 + 643 + static bool fw_force_sysfs_fallback(unsigned int opt_flags) 644 + { 645 + if (fw_fallback_config.force_sysfs_fallback) 646 + return true; 647 + if (!(opt_flags & FW_OPT_USERHELPER)) 648 + return false; 649 + return true; 650 + } 651 + 652 + static bool fw_run_sysfs_fallback(unsigned int opt_flags) 653 + { 654 + if (fw_fallback_config.ignore_sysfs_fallback) { 655 + pr_info_once("Ignoring firmware sysfs fallback due to sysctl knob\n"); 656 + return false; 657 + } 658 + 659 + if ((opt_flags & FW_OPT_NOFALLBACK)) 660 + return false; 661 + 662 + return fw_force_sysfs_fallback(opt_flags); 663 + } 664 + 665 + int fw_sysfs_fallback(struct firmware *fw, const char *name, 666 + struct device *device, 667 + unsigned int opt_flags, 668 + int ret) 669 + { 670 + if (!fw_run_sysfs_fallback(opt_flags)) 671 + return ret; 672 + 673 + dev_warn(device, "Falling back to user helper\n"); 674 + return fw_load_from_user_helper(fw, name, device, opt_flags); 675 + }
+67
drivers/base/firmware_loader/fallback.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __FIRMWARE_FALLBACK_H 3 + #define __FIRMWARE_FALLBACK_H 4 + 5 + #include <linux/firmware.h> 6 + #include <linux/device.h> 7 + 8 + /** 9 + * struct firmware_fallback_config - firmware fallback configuratioon settings 10 + * 11 + * Helps describe and fine tune the fallback mechanism. 12 + * 13 + * @force_sysfs_fallback: force the sysfs fallback mechanism to be used 14 + * as if one had enabled CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y. 15 + * Useful to help debug a CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y 16 + * functionality on a kernel where that config entry has been disabled. 17 + * @ignore_sysfs_fallback: force to disable the sysfs fallback mechanism. 18 + * This emulates the behaviour as if we had set the kernel 19 + * config CONFIG_FW_LOADER_USER_HELPER=n. 20 + * @old_timeout: for internal use 21 + * @loading_timeout: the timeout to wait for the fallback mechanism before 22 + * giving up, in seconds. 23 + */ 24 + struct firmware_fallback_config { 25 + unsigned int force_sysfs_fallback; 26 + unsigned int ignore_sysfs_fallback; 27 + int old_timeout; 28 + int loading_timeout; 29 + }; 30 + 31 + #ifdef CONFIG_FW_LOADER_USER_HELPER 32 + int fw_sysfs_fallback(struct firmware *fw, const char *name, 33 + struct device *device, 34 + unsigned int opt_flags, 35 + int ret); 36 + void kill_pending_fw_fallback_reqs(bool only_kill_custom); 37 + 38 + void fw_fallback_set_cache_timeout(void); 39 + void fw_fallback_set_default_timeout(void); 40 + 41 + int register_sysfs_loader(void); 42 + void unregister_sysfs_loader(void); 43 + #else /* CONFIG_FW_LOADER_USER_HELPER */ 44 + static inline int fw_sysfs_fallback(struct firmware *fw, const char *name, 45 + struct device *device, 46 + unsigned int opt_flags, 47 + int ret) 48 + { 49 + /* Keep carrying over the same error */ 50 + return ret; 51 + } 52 + 53 + static inline void kill_pending_fw_fallback_reqs(bool only_kill_custom) { } 54 + static inline void fw_fallback_set_cache_timeout(void) { } 55 + static inline void fw_fallback_set_default_timeout(void) { } 56 + 57 + static inline int register_sysfs_loader(void) 58 + { 59 + return 0; 60 + } 61 + 62 + static inline void unregister_sysfs_loader(void) 63 + { 64 + } 65 + #endif /* CONFIG_FW_LOADER_USER_HELPER */ 66 + 67 + #endif /* __FIRMWARE_FALLBACK_H */
+55
drivers/base/firmware_loader/fallback_table.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/types.h> 4 + #include <linux/kconfig.h> 5 + #include <linux/list.h> 6 + #include <linux/slab.h> 7 + #include <linux/security.h> 8 + #include <linux/highmem.h> 9 + #include <linux/umh.h> 10 + #include <linux/sysctl.h> 11 + 12 + #include "fallback.h" 13 + #include "firmware.h" 14 + 15 + /* 16 + * firmware fallback configuration table 17 + */ 18 + 19 + /* Module or buit-in */ 20 + #ifdef CONFIG_FW_LOADER_USER_HELPER 21 + 22 + static unsigned int zero; 23 + static unsigned int one = 1; 24 + 25 + struct firmware_fallback_config fw_fallback_config = { 26 + .force_sysfs_fallback = IS_ENABLED(CONFIG_FW_LOADER_USER_HELPER_FALLBACK), 27 + .loading_timeout = 60, 28 + .old_timeout = 60, 29 + }; 30 + EXPORT_SYMBOL_GPL(fw_fallback_config); 31 + 32 + struct ctl_table firmware_config_table[] = { 33 + { 34 + .procname = "force_sysfs_fallback", 35 + .data = &fw_fallback_config.force_sysfs_fallback, 36 + .maxlen = sizeof(unsigned int), 37 + .mode = 0644, 38 + .proc_handler = proc_douintvec_minmax, 39 + .extra1 = &zero, 40 + .extra2 = &one, 41 + }, 42 + { 43 + .procname = "ignore_sysfs_fallback", 44 + .data = &fw_fallback_config.ignore_sysfs_fallback, 45 + .maxlen = sizeof(unsigned int), 46 + .mode = 0644, 47 + .proc_handler = proc_douintvec_minmax, 48 + .extra1 = &zero, 49 + .extra2 = &one, 50 + }, 51 + { } 52 + }; 53 + EXPORT_SYMBOL_GPL(firmware_config_table); 54 + 55 + #endif
+115
drivers/base/firmware_loader/firmware.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __FIRMWARE_LOADER_H 3 + #define __FIRMWARE_LOADER_H 4 + 5 + #include <linux/firmware.h> 6 + #include <linux/types.h> 7 + #include <linux/kref.h> 8 + #include <linux/list.h> 9 + #include <linux/completion.h> 10 + 11 + #include <generated/utsrelease.h> 12 + 13 + /* firmware behavior options */ 14 + #define FW_OPT_UEVENT (1U << 0) 15 + #define FW_OPT_NOWAIT (1U << 1) 16 + #define FW_OPT_USERHELPER (1U << 2) 17 + #define FW_OPT_NO_WARN (1U << 3) 18 + #define FW_OPT_NOCACHE (1U << 4) 19 + #define FW_OPT_NOFALLBACK (1U << 5) 20 + 21 + enum fw_status { 22 + FW_STATUS_UNKNOWN, 23 + FW_STATUS_LOADING, 24 + FW_STATUS_DONE, 25 + FW_STATUS_ABORTED, 26 + }; 27 + 28 + /* 29 + * Concurrent request_firmware() for the same firmware need to be 30 + * serialized. struct fw_state is simple state machine which hold the 31 + * state of the firmware loading. 32 + */ 33 + struct fw_state { 34 + struct completion completion; 35 + enum fw_status status; 36 + }; 37 + 38 + struct fw_priv { 39 + struct kref ref; 40 + struct list_head list; 41 + struct firmware_cache *fwc; 42 + struct fw_state fw_st; 43 + void *data; 44 + size_t size; 45 + size_t allocated_size; 46 + #ifdef CONFIG_FW_LOADER_USER_HELPER 47 + bool is_paged_buf; 48 + bool need_uevent; 49 + struct page **pages; 50 + int nr_pages; 51 + int page_array_size; 52 + struct list_head pending_list; 53 + #endif 54 + const char *fw_name; 55 + }; 56 + 57 + extern struct mutex fw_lock; 58 + 59 + static inline bool __fw_state_check(struct fw_priv *fw_priv, 60 + enum fw_status status) 61 + { 62 + struct fw_state *fw_st = &fw_priv->fw_st; 63 + 64 + return fw_st->status == status; 65 + } 66 + 67 + static inline int __fw_state_wait_common(struct fw_priv *fw_priv, long timeout) 68 + { 69 + struct fw_state *fw_st = &fw_priv->fw_st; 70 + long ret; 71 + 72 + ret = wait_for_completion_killable_timeout(&fw_st->completion, timeout); 73 + if (ret != 0 && fw_st->status == FW_STATUS_ABORTED) 74 + return -ENOENT; 75 + if (!ret) 76 + return -ETIMEDOUT; 77 + 78 + return ret < 0 ? ret : 0; 79 + } 80 + 81 + static inline void __fw_state_set(struct fw_priv *fw_priv, 82 + enum fw_status status) 83 + { 84 + struct fw_state *fw_st = &fw_priv->fw_st; 85 + 86 + WRITE_ONCE(fw_st->status, status); 87 + 88 + if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) 89 + complete_all(&fw_st->completion); 90 + } 91 + 92 + static inline void fw_state_aborted(struct fw_priv *fw_priv) 93 + { 94 + __fw_state_set(fw_priv, FW_STATUS_ABORTED); 95 + } 96 + 97 + static inline bool fw_state_is_aborted(struct fw_priv *fw_priv) 98 + { 99 + return __fw_state_check(fw_priv, FW_STATUS_ABORTED); 100 + } 101 + 102 + static inline void fw_state_start(struct fw_priv *fw_priv) 103 + { 104 + __fw_state_set(fw_priv, FW_STATUS_LOADING); 105 + } 106 + 107 + static inline void fw_state_done(struct fw_priv *fw_priv) 108 + { 109 + __fw_state_set(fw_priv, FW_STATUS_DONE); 110 + } 111 + 112 + int assign_fw(struct firmware *fw, struct device *device, 113 + unsigned int opt_flags); 114 + 115 + #endif /* __FIRMWARE_LOADER_H */
+3 -1
drivers/base/node.c
··· 315 315 node->dev.groups = node_dev_groups; 316 316 error = device_register(&node->dev); 317 317 318 - if (!error){ 318 + if (error) 319 + put_device(&node->dev); 320 + else { 319 321 hugetlb_register_node(node); 320 322 321 323 compaction_register_node(node);
+3 -1
drivers/base/platform.c
··· 1153 1153 early_platform_cleanup(); 1154 1154 1155 1155 error = device_register(&platform_bus); 1156 - if (error) 1156 + if (error) { 1157 + put_device(&platform_bus); 1157 1158 return error; 1159 + } 1158 1160 error = bus_register(&platform_bus_type); 1159 1161 if (error) 1160 1162 device_unregister(&platform_bus);
+2
drivers/base/soc.c
··· 150 150 151 151 out3: 152 152 ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); 153 + put_device(&soc_dev->dev); 154 + soc_dev = NULL; 153 155 out2: 154 156 kfree(soc_dev); 155 157 out1:
+1 -1
drivers/net/wireless/mediatek/mt7601u/mcu.c
··· 420 420 MT_USB_DMA_CFG_TX_BULK_EN)); 421 421 422 422 if (firmware_running(dev)) 423 - return 0; 423 + return firmware_request_cache(dev->dev, MT7601U_FIRMWARE); 424 424 425 425 ret = request_firmware(&fw, MT7601U_FIRMWARE, dev->dev); 426 426 if (ret)
+1
include/linux/device.h
··· 256 256 * automatically. 257 257 * @pm: Power management operations of the device which matched 258 258 * this driver. 259 + * @coredump: Called through sysfs to initiate a device coredump. 259 260 * @p: Driver core's private data, no one other than the driver 260 261 * core can touch this. 261 262 *
+3
include/linux/firmware.h
··· 85 85 } 86 86 87 87 #endif 88 + 89 + int firmware_request_cache(struct device *device, const char *name); 90 + 88 91 #endif
+11
kernel/sysctl.c
··· 253 253 extern struct ctl_table epoll_table[]; 254 254 #endif 255 255 256 + #ifdef CONFIG_FW_LOADER_USER_HELPER 257 + extern struct ctl_table firmware_config_table[]; 258 + #endif 259 + 256 260 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT 257 261 int sysctl_legacy_va_layout; 258 262 #endif ··· 752 748 .mode = 0555, 753 749 .child = usermodehelper_table, 754 750 }, 751 + #ifdef CONFIG_FW_LOADER_USER_HELPER 752 + { 753 + .procname = "firmware_config", 754 + .mode = 0555, 755 + .child = firmware_config_table, 756 + }, 757 + #endif 755 758 { 756 759 .procname = "overflowuid", 757 760 .data = &overflowuid,
+18 -21
lib/kobject.c
··· 204 204 return -ENOENT; 205 205 206 206 if (!kobj->name || !kobj->name[0]) { 207 - WARN(1, "kobject: (%p): attempted to be registered with empty " 208 - "name!\n", kobj); 207 + WARN(1, 208 + "kobject: (%p): attempted to be registered with empty name!\n", 209 + kobj); 209 210 return -EINVAL; 210 211 } 211 212 ··· 233 232 234 233 /* be noisy on error issues */ 235 234 if (error == -EEXIST) 236 - WARN(1, "%s failed for %s with " 237 - "-EEXIST, don't try to register things with " 238 - "the same name in the same directory.\n", 235 + WARN(1, 236 + "%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n", 239 237 __func__, kobject_name(kobj)); 240 238 else 241 239 WARN(1, "%s failed for %s (error: %d parent: %s)\n", ··· 334 334 } 335 335 if (kobj->state_initialized) { 336 336 /* do not error out as sometimes we can recover */ 337 - printk(KERN_ERR "kobject (%p): tried to init an initialized " 338 - "object, something is seriously wrong.\n", kobj); 337 + pr_err("kobject (%p): tried to init an initialized object, something is seriously wrong.\n", 338 + kobj); 339 339 dump_stack(); 340 340 } 341 341 ··· 344 344 return; 345 345 346 346 error: 347 - printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str); 347 + pr_err("kobject (%p): %s\n", kobj, err_str); 348 348 dump_stack(); 349 349 } 350 350 EXPORT_SYMBOL(kobject_init); ··· 357 357 358 358 retval = kobject_set_name_vargs(kobj, fmt, vargs); 359 359 if (retval) { 360 - printk(KERN_ERR "kobject: can not set name properly!\n"); 360 + pr_err("kobject: can not set name properly!\n"); 361 361 return retval; 362 362 } 363 363 kobj->parent = parent; ··· 399 399 return -EINVAL; 400 400 401 401 if (!kobj->state_initialized) { 402 - printk(KERN_ERR "kobject '%s' (%p): tried to add an " 403 - "uninitialized object, something is seriously wrong.\n", 402 + pr_err("kobject '%s' (%p): tried to add an uninitialized object, something is seriously wrong.\n", 404 403 kobject_name(kobj), kobj); 405 404 dump_stack(); 406 405 return -EINVAL; ··· 589 590 { 590 591 if (kobj) { 591 592 if (!kobj->state_initialized) 592 - WARN(1, KERN_WARNING "kobject: '%s' (%p): is not " 593 - "initialized, yet kobject_get() is being " 594 - "called.\n", kobject_name(kobj), kobj); 593 + WARN(1, KERN_WARNING 594 + "kobject: '%s' (%p): is not initialized, yet kobject_get() is being called.\n", 595 + kobject_name(kobj), kobj); 595 596 kref_get(&kobj->kref); 596 597 } 597 598 return kobj; ··· 621 622 kobject_name(kobj), kobj, __func__, kobj->parent); 622 623 623 624 if (t && !t->release) 624 - pr_debug("kobject: '%s' (%p): does not have a release() " 625 - "function, it is broken and must be fixed.\n", 625 + pr_debug("kobject: '%s' (%p): does not have a release() function, it is broken and must be fixed.\n", 626 626 kobject_name(kobj), kobj); 627 627 628 628 /* send "remove" if the caller did not do it but sent "add" */ ··· 684 686 { 685 687 if (kobj) { 686 688 if (!kobj->state_initialized) 687 - WARN(1, KERN_WARNING "kobject: '%s' (%p): is not " 688 - "initialized, yet kobject_put() is being " 689 - "called.\n", kobject_name(kobj), kobj); 689 + WARN(1, KERN_WARNING 690 + "kobject: '%s' (%p): is not initialized, yet kobject_put() is being called.\n", 691 + kobject_name(kobj), kobj); 690 692 kref_put(&kobj->kref, kobject_release); 691 693 } 692 694 } ··· 750 752 751 753 retval = kobject_add(kobj, parent, "%s", name); 752 754 if (retval) { 753 - printk(KERN_WARNING "%s: kobject_add error: %d\n", 754 - __func__, retval); 755 + pr_warn("%s: kobject_add error: %d\n", __func__, retval); 755 756 kobject_put(kobj); 756 757 kobj = NULL; 757 758 }
+1 -1
tools/testing/selftests/firmware/Makefile
··· 3 3 # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 4 4 all: 5 5 6 - TEST_PROGS := fw_filesystem.sh fw_fallback.sh 6 + TEST_PROGS := fw_run_tests.sh 7 7 8 8 include ../lib.mk 9 9
+4
tools/testing/selftests/firmware/config
··· 1 1 CONFIG_TEST_FIRMWARE=y 2 + CONFIG_FW_LOADER=y 3 + CONFIG_FW_LOADER_USER_HELPER=y 4 + CONFIG_IKCONFIG=y 5 + CONFIG_IKCONFIG_PROC=y
+28 -37
tools/testing/selftests/firmware/fw_fallback.sh
··· 1 - #!/bin/sh 1 + #!/bin/bash 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # This validates that the kernel will fall back to using the fallback mechanism 4 4 # to load firmware it can't find on disk itself. We must request a firmware ··· 6 6 # won't find so that we can do the load ourself manually. 7 7 set -e 8 8 9 - modprobe test_firmware 9 + TEST_REQS_FW_SYSFS_FALLBACK="yes" 10 + TEST_REQS_FW_SET_CUSTOM_PATH="no" 11 + TEST_DIR=$(dirname $0) 12 + source $TEST_DIR/fw_lib.sh 10 13 11 - DIR=/sys/devices/virtual/misc/test_firmware 14 + check_mods 15 + check_setup 16 + verify_reqs 17 + setup_tmp_file 12 18 13 - # CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/ 14 - # These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that 15 - # as an indicator for CONFIG_FW_LOADER_USER_HELPER. 16 - HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi) 17 - 18 - if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 19 - OLD_TIMEOUT=$(cat /sys/class/firmware/timeout) 20 - else 21 - echo "usermode helper disabled so ignoring test" 22 - exit 0 23 - fi 24 - 25 - FWPATH=$(mktemp -d) 26 - FW="$FWPATH/test-firmware.bin" 27 - 28 - test_finish() 29 - { 30 - echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout 31 - rm -f "$FW" 32 - rmdir "$FWPATH" 33 - } 19 + trap "test_finish" EXIT 34 20 35 21 load_fw() 36 22 { ··· 155 169 return $RET 156 170 } 157 171 158 - trap "test_finish" EXIT 159 - 160 - # This is an unlikely real-world firmware content. :) 161 - echo "ABCD0123" >"$FW" 162 - NAME=$(basename "$FW") 163 - 164 172 test_syfs_timeout() 165 173 { 166 174 DEVPATH="$DIR"/"nope-$NAME"/loading ··· 238 258 239 259 run_sysfs_custom_load_tests() 240 260 { 241 - if load_fw_custom "$NAME" "$FW" ; then 242 - if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then 261 + RANDOM_FILE_PATH=$(setup_random_file) 262 + RANDOM_FILE="$(basename $RANDOM_FILE_PATH)" 263 + if load_fw_custom "$RANDOM_FILE" "$RANDOM_FILE_PATH" ; then 264 + if ! diff -q "$RANDOM_FILE_PATH" /dev/test_firmware >/dev/null ; then 243 265 echo "$0: firmware was not loaded" >&2 244 266 exit 1 245 267 else ··· 249 267 fi 250 268 fi 251 269 252 - if load_fw_custom "$NAME" "$FW" ; then 253 - if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then 270 + RANDOM_FILE_PATH=$(setup_random_file) 271 + RANDOM_FILE="$(basename $RANDOM_FILE_PATH)" 272 + if load_fw_custom "$RANDOM_FILE" "$RANDOM_FILE_PATH" ; then 273 + if ! diff -q "$RANDOM_FILE_PATH" /dev/test_firmware >/dev/null ; then 254 274 echo "$0: firmware was not loaded" >&2 255 275 exit 1 256 276 else ··· 260 276 fi 261 277 fi 262 278 263 - if load_fw_custom_cancel "nope-$NAME" "$FW" ; then 264 - if diff -q "$FW" /dev/test_firmware >/dev/null ; then 279 + RANDOM_FILE_REAL="$RANDOM_FILE_PATH" 280 + FAKE_RANDOM_FILE_PATH=$(setup_random_file_fake) 281 + FAKE_RANDOM_FILE="$(basename $FAKE_RANDOM_FILE_PATH)" 282 + 283 + if load_fw_custom_cancel "$FAKE_RANDOM_FILE" "$RANDOM_FILE_REAL" ; then 284 + if diff -q "$RANDOM_FILE_PATH" /dev/test_firmware >/dev/null ; then 265 285 echo "$0: firmware was expected to be cancelled" >&2 266 286 exit 1 267 287 else ··· 274 286 fi 275 287 } 276 288 277 - run_sysfs_main_tests 289 + if [ "$HAS_FW_LOADER_USER_HELPER_FALLBACK" = "yes" ]; then 290 + run_sysfs_main_tests 291 + fi 292 + 278 293 run_sysfs_custom_load_tests 279 294 280 295 exit 0
+17 -55
tools/testing/selftests/firmware/fw_filesystem.sh
··· 1 - #!/bin/sh 1 + #!/bin/bash 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # This validates that the kernel will load firmware out of its list of 4 4 # firmware locations on disk. Since the user helper does similar work, ··· 6 6 # know so we can be sure we're not accidentally testing the user helper. 7 7 set -e 8 8 9 - DIR=/sys/devices/virtual/misc/test_firmware 9 + TEST_REQS_FW_SYSFS_FALLBACK="no" 10 + TEST_REQS_FW_SET_CUSTOM_PATH="yes" 10 11 TEST_DIR=$(dirname $0) 12 + source $TEST_DIR/fw_lib.sh 11 13 12 - test_modprobe() 13 - { 14 - if [ ! -d $DIR ]; then 15 - echo "$0: $DIR not present" 16 - echo "You must have the following enabled in your kernel:" 17 - cat $TEST_DIR/config 18 - exit 1 19 - fi 20 - } 21 - 22 - trap "test_modprobe" EXIT 23 - 24 - if [ ! -d $DIR ]; then 25 - modprobe test_firmware 26 - fi 27 - 28 - # CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/ 29 - # These days most distros enable CONFIG_FW_LOADER_USER_HELPER but disable 30 - # CONFIG_FW_LOADER_USER_HELPER_FALLBACK. We use /sys/class/firmware/ as an 31 - # indicator for CONFIG_FW_LOADER_USER_HELPER. 32 - HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi) 33 - 34 - if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 35 - OLD_TIMEOUT=$(cat /sys/class/firmware/timeout) 36 - fi 37 - 38 - OLD_FWPATH=$(cat /sys/module/firmware_class/parameters/path) 39 - 40 - FWPATH=$(mktemp -d) 41 - FW="$FWPATH/test-firmware.bin" 42 - 43 - test_finish() 44 - { 45 - if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 46 - echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout 47 - fi 48 - if [ "$OLD_FWPATH" = "" ]; then 49 - OLD_FWPATH=" " 50 - fi 51 - echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path 52 - rm -f "$FW" 53 - rmdir "$FWPATH" 54 - } 14 + check_mods 15 + check_setup 16 + verify_reqs 17 + setup_tmp_file 55 18 56 19 trap "test_finish" EXIT 57 20 ··· 22 59 # Turn down the timeout so failures don't take so long. 23 60 echo 1 >/sys/class/firmware/timeout 24 61 fi 25 - 26 - # Set the kernel search path. 27 - echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path 28 - 29 - # This is an unlikely real-world firmware content. :) 30 - echo "ABCD0123" >"$FW" 31 - 32 - NAME=$(basename "$FW") 33 62 34 63 if printf '\000' >"$DIR"/trigger_request 2> /dev/null; then 35 64 echo "$0: empty filename should not succeed" >&2 ··· 230 275 test_request_firmware_nowait_custom_nofile() 231 276 { 232 277 echo -n "Batched request_firmware_nowait(uevent=false) nofile try #$1: " 278 + config_reset 233 279 config_unset_uevent 234 - config_set_name nope-test-firmware.bin 280 + RANDOM_FILE_PATH=$(setup_random_file_fake) 281 + RANDOM_FILE="$(basename $RANDOM_FILE_PATH)" 282 + config_set_name $RANDOM_FILE 235 283 config_trigger_async & 236 - test_wait_and_cancel_custom_load nope-test-firmware.bin 284 + test_wait_and_cancel_custom_load $RANDOM_FILE 237 285 wait 238 286 release_all_firmware 239 287 echo "OK" ··· 274 316 test_request_firmware_nowait_custom() 275 317 { 276 318 echo -n "Batched request_firmware_nowait(uevent=false) try #$1: " 319 + config_reset 277 320 config_unset_uevent 321 + RANDOM_FILE_PATH=$(setup_random_file) 322 + RANDOM_FILE="$(basename $RANDOM_FILE_PATH)" 323 + config_set_name $RANDOM_FILE 278 324 config_trigger_async 279 325 release_all_firmware 280 326 echo "OK"
+194
tools/testing/selftests/firmware/fw_lib.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # Library of helpers for test scripts. 5 + set -e 6 + 7 + DIR=/sys/devices/virtual/misc/test_firmware 8 + 9 + PROC_CONFIG="/proc/config.gz" 10 + TEST_DIR=$(dirname $0) 11 + 12 + print_reqs_exit() 13 + { 14 + echo "You must have the following enabled in your kernel:" >&2 15 + cat $TEST_DIR/config >&2 16 + exit 1 17 + } 18 + 19 + test_modprobe() 20 + { 21 + if [ ! -d $DIR ]; then 22 + print_reqs_exit 23 + fi 24 + } 25 + 26 + check_mods() 27 + { 28 + trap "test_modprobe" EXIT 29 + if [ ! -d $DIR ]; then 30 + modprobe test_firmware 31 + fi 32 + if [ ! -f $PROC_CONFIG ]; then 33 + if modprobe configs 2>/dev/null; then 34 + echo "Loaded configs module" 35 + if [ ! -f $PROC_CONFIG ]; then 36 + echo "You must have the following enabled in your kernel:" >&2 37 + cat $TEST_DIR/config >&2 38 + echo "Resorting to old heuristics" >&2 39 + fi 40 + else 41 + echo "Failed to load configs module, using old heuristics" >&2 42 + fi 43 + fi 44 + } 45 + 46 + check_setup() 47 + { 48 + HAS_FW_LOADER_USER_HELPER="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER=y)" 49 + HAS_FW_LOADER_USER_HELPER_FALLBACK="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y)" 50 + PROC_FW_IGNORE_SYSFS_FALLBACK="0" 51 + PROC_FW_FORCE_SYSFS_FALLBACK="0" 52 + 53 + if [ -z $PROC_SYS_DIR ]; then 54 + PROC_SYS_DIR="/proc/sys/kernel" 55 + fi 56 + 57 + FW_PROC="${PROC_SYS_DIR}/firmware_config" 58 + FW_FORCE_SYSFS_FALLBACK="$FW_PROC/force_sysfs_fallback" 59 + FW_IGNORE_SYSFS_FALLBACK="$FW_PROC/ignore_sysfs_fallback" 60 + 61 + if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then 62 + PROC_FW_FORCE_SYSFS_FALLBACK="$(cat $FW_FORCE_SYSFS_FALLBACK)" 63 + fi 64 + 65 + if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then 66 + PROC_FW_IGNORE_SYSFS_FALLBACK="$(cat $FW_IGNORE_SYSFS_FALLBACK)" 67 + fi 68 + 69 + if [ "$PROC_FW_FORCE_SYSFS_FALLBACK" = "1" ]; then 70 + HAS_FW_LOADER_USER_HELPER="yes" 71 + HAS_FW_LOADER_USER_HELPER_FALLBACK="yes" 72 + fi 73 + 74 + if [ "$PROC_FW_IGNORE_SYSFS_FALLBACK" = "1" ]; then 75 + HAS_FW_LOADER_USER_HELPER_FALLBACK="no" 76 + HAS_FW_LOADER_USER_HELPER="no" 77 + fi 78 + 79 + if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 80 + OLD_TIMEOUT="$(cat /sys/class/firmware/timeout)" 81 + fi 82 + 83 + OLD_FWPATH="$(cat /sys/module/firmware_class/parameters/path)" 84 + } 85 + 86 + verify_reqs() 87 + { 88 + if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then 89 + if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 90 + echo "usermode helper disabled so ignoring test" 91 + exit 0 92 + fi 93 + fi 94 + } 95 + 96 + setup_tmp_file() 97 + { 98 + FWPATH=$(mktemp -d) 99 + FW="$FWPATH/test-firmware.bin" 100 + echo "ABCD0123" >"$FW" 101 + NAME=$(basename "$FW") 102 + if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then 103 + echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path 104 + fi 105 + } 106 + 107 + __setup_random_file() 108 + { 109 + RANDOM_FILE_PATH="$(mktemp -p $FWPATH)" 110 + # mktemp says dry-run -n is unsafe, so... 111 + if [[ "$1" = "fake" ]]; then 112 + rm -rf $RANDOM_FILE_PATH 113 + sync 114 + else 115 + echo "ABCD0123" >"$RANDOM_FILE_PATH" 116 + fi 117 + echo $RANDOM_FILE_PATH 118 + } 119 + 120 + setup_random_file() 121 + { 122 + echo $(__setup_random_file) 123 + } 124 + 125 + setup_random_file_fake() 126 + { 127 + echo $(__setup_random_file fake) 128 + } 129 + 130 + proc_set_force_sysfs_fallback() 131 + { 132 + if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then 133 + echo -n $1 > $FW_FORCE_SYSFS_FALLBACK 134 + check_setup 135 + fi 136 + } 137 + 138 + proc_set_ignore_sysfs_fallback() 139 + { 140 + if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then 141 + echo -n $1 > $FW_IGNORE_SYSFS_FALLBACK 142 + check_setup 143 + fi 144 + } 145 + 146 + proc_restore_defaults() 147 + { 148 + proc_set_force_sysfs_fallback 0 149 + proc_set_ignore_sysfs_fallback 0 150 + } 151 + 152 + test_finish() 153 + { 154 + if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 155 + echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout 156 + fi 157 + if [ "$OLD_FWPATH" = "" ]; then 158 + OLD_FWPATH=" " 159 + fi 160 + if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then 161 + echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path 162 + fi 163 + if [ -f $FW ]; then 164 + rm -f "$FW" 165 + fi 166 + if [ -d $FWPATH ]; then 167 + rm -rf "$FWPATH" 168 + fi 169 + proc_restore_defaults 170 + } 171 + 172 + kconfig_has() 173 + { 174 + if [ -f $PROC_CONFIG ]; then 175 + if zgrep -q $1 $PROC_CONFIG 2>/dev/null; then 176 + echo "yes" 177 + else 178 + echo "no" 179 + fi 180 + else 181 + # We currently don't have easy heuristics to infer this 182 + # so best we can do is just try to use the kernel assuming 183 + # you had enabled it. This matches the old behaviour. 184 + if [ "$1" = "CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y" ]; then 185 + echo "yes" 186 + elif [ "$1" = "CONFIG_FW_LOADER_USER_HELPER=y" ]; then 187 + if [ -d /sys/class/firmware/ ]; then 188 + echo yes 189 + else 190 + echo no 191 + fi 192 + fi 193 + fi 194 + }
+70
tools/testing/selftests/firmware/fw_run_tests.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # This runs all known tests across all known possible configurations we could 5 + # emulate in one run. 6 + 7 + set -e 8 + 9 + TEST_DIR=$(dirname $0) 10 + source $TEST_DIR/fw_lib.sh 11 + 12 + export HAS_FW_LOADER_USER_HELPER="" 13 + export HAS_FW_LOADER_USER_HELPER_FALLBACK="" 14 + 15 + run_tests() 16 + { 17 + proc_set_force_sysfs_fallback $1 18 + proc_set_ignore_sysfs_fallback $2 19 + $TEST_DIR/fw_filesystem.sh 20 + 21 + proc_set_force_sysfs_fallback $1 22 + proc_set_ignore_sysfs_fallback $2 23 + $TEST_DIR/fw_fallback.sh 24 + } 25 + 26 + run_test_config_0001() 27 + { 28 + echo "-----------------------------------------------------" 29 + echo "Running kernel configuration test 1 -- rare" 30 + echo "Emulates:" 31 + echo "CONFIG_FW_LOADER=y" 32 + echo "CONFIG_FW_LOADER_USER_HELPER=n" 33 + echo "CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n" 34 + run_tests 0 1 35 + } 36 + 37 + run_test_config_0002() 38 + { 39 + echo "-----------------------------------------------------" 40 + echo "Running kernel configuration test 2 -- distro" 41 + echo "Emulates:" 42 + echo "CONFIG_FW_LOADER=y" 43 + echo "CONFIG_FW_LOADER_USER_HELPER=y" 44 + echo "CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n" 45 + proc_set_ignore_sysfs_fallback 0 46 + run_tests 0 0 47 + } 48 + 49 + run_test_config_0003() 50 + { 51 + echo "-----------------------------------------------------" 52 + echo "Running kernel configuration test 3 -- android" 53 + echo "Emulates:" 54 + echo "CONFIG_FW_LOADER=y" 55 + echo "CONFIG_FW_LOADER_USER_HELPER=y" 56 + echo "CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y" 57 + run_tests 1 0 58 + } 59 + 60 + check_mods 61 + check_setup 62 + 63 + if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then 64 + run_test_config_0001 65 + run_test_config_0002 66 + run_test_config_0003 67 + else 68 + echo "Running basic kernel configuration, working with your config" 69 + run_test 70 + fi