Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0 2 : /* Builtin firmware support */ 3 : 4 : #include <linux/firmware.h> 5 : #include "../firmware.h" 6 : 7 : /* Only if FW_LOADER=y */ 8 : #ifdef CONFIG_FW_LOADER 9 : 10 : struct builtin_fw { 11 : char *name; 12 : void *data; 13 : unsigned long size; 14 : }; 15 : 16 : extern struct builtin_fw __start_builtin_fw[]; 17 : extern struct builtin_fw __end_builtin_fw[]; 18 : 19 0 : static bool fw_copy_to_prealloc_buf(struct firmware *fw, 20 : void *buf, size_t size) 21 : { 22 0 : if (!buf) 23 : return true; 24 0 : if (size < fw->size) 25 : return false; 26 0 : memcpy(buf, fw->data, fw->size); 27 : return true; 28 : } 29 : 30 : /** 31 : * firmware_request_builtin() - load builtin firmware 32 : * @fw: pointer to firmware struct 33 : * @name: name of firmware file 34 : * 35 : * Some use cases in the kernel have a requirement so that no memory allocator 36 : * is involved as these calls take place early in boot process. An example is 37 : * the x86 CPU microcode loader. In these cases all the caller wants is to see 38 : * if the firmware was built-in and if so use it right away. This can be used 39 : * for such cases. 40 : * 41 : * This looks for the firmware in the built-in kernel. Only if the kernel was 42 : * built-in with the firmware you are looking for will this return successfully. 43 : * 44 : * Callers of this API do not need to use release_firmware() as the pointer to 45 : * the firmware is expected to be provided locally on the stack of the caller. 46 : **/ 47 0 : bool firmware_request_builtin(struct firmware *fw, const char *name) 48 : { 49 : struct builtin_fw *b_fw; 50 : 51 0 : if (!fw) 52 : return false; 53 : 54 0 : for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { 55 0 : if (strcmp(name, b_fw->name) == 0) { 56 0 : fw->size = b_fw->size; 57 0 : fw->data = b_fw->data; 58 0 : return true; 59 : } 60 : } 61 : 62 : return false; 63 : } 64 : EXPORT_SYMBOL_NS_GPL(firmware_request_builtin, TEST_FIRMWARE); 65 : 66 : /** 67 : * firmware_request_builtin_buf() - load builtin firmware into optional buffer 68 : * @fw: pointer to firmware struct 69 : * @name: name of firmware file 70 : * @buf: If set this lets you use a pre-allocated buffer so that the built-in 71 : * firmware into is copied into. This field can be NULL. It is used by 72 : * callers such as request_firmware_into_buf() and 73 : * request_partial_firmware_into_buf() 74 : * @size: if buf was provided, the max size of the allocated buffer available. 75 : * If the built-in firmware does not fit into the pre-allocated @buf this 76 : * call will fail. 77 : * 78 : * This looks for the firmware in the built-in kernel. Only if the kernel was 79 : * built-in with the firmware you are looking for will this call possibly 80 : * succeed. If you passed a @buf the firmware will be copied into it *iff* the 81 : * built-in firmware fits into the pre-allocated buffer size specified in 82 : * @size. 83 : * 84 : * This caller is to be used internally by the firmware_loader only. 85 : **/ 86 0 : bool firmware_request_builtin_buf(struct firmware *fw, const char *name, 87 : void *buf, size_t size) 88 : { 89 0 : if (!firmware_request_builtin(fw, name)) 90 : return false; 91 : 92 0 : return fw_copy_to_prealloc_buf(fw, buf, size); 93 : } 94 : 95 0 : bool firmware_is_builtin(const struct firmware *fw) 96 : { 97 : struct builtin_fw *b_fw; 98 : 99 0 : for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) 100 0 : if (fw->data == b_fw->data) 101 : return true; 102 : 103 : return false; 104 : } 105 : 106 : #endif