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

firmware loader: inform direct failure when udev loader is disabled

Now that the udev firmware loader is optional request_firmware()
will not provide any information on the kernel ring buffer if
direct firmware loading failed and udev firmware loading is disabled.
If no information is needed request_firmware_direct() should be used
for optional firmware, at which point drivers can take on the onus
over informing of any failures, if udev firmware loading is disabled
though we should at the very least provide some sort of information
as when the udev loader was enabled by default back in the days.

With this change with a simple firmware load test module [0]:

Example output without FW_LOADER_USER_HELPER_FALLBACK

platform fake-dev.0: Direct firmware load for fake.bin failed
with error -2

Example with FW_LOADER_USER_HELPER_FALLBACK

platform fake-dev.0: Direct firmware load for fake.bin failed with error -2
platform fake-dev.0: Falling back to user helper

Without this change without FW_LOADER_USER_HELPER_FALLBACK we
get no output logged upon failure.

Cc: Tom Gundersen <teg@jklm.no>
Cc: Ming Lei <ming.lei@canonical.com>
Cc: Abhay Salunke <Abhay_Salunke@dell.com>
Cc: Stefan Roese <sr@denx.de>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kay Sievers <kay@vrfy.org>
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Luis R. Rodriguez and committed by
Greg Kroah-Hartman
c868edf4 a76040d8

+15 -13
+7 -6
drivers/base/firmware_class.c
··· 109 109 #else 110 110 #define FW_OPT_FALLBACK 0 111 111 #endif 112 + #define FW_OPT_NO_WARN (1U << 3) 112 113 113 114 struct firmware_cache { 114 115 /* firmware_buf instance will be added into the below list */ ··· 1106 1105 1107 1106 ret = fw_get_filesystem_firmware(device, fw->priv); 1108 1107 if (ret) { 1109 - if (opt_flags & FW_OPT_USERHELPER) { 1108 + if (!(opt_flags & FW_OPT_NO_WARN)) 1110 1109 dev_warn(device, 1111 - "Direct firmware load failed with error %d\n", 1112 - ret); 1110 + "Direct firmware load for %s failed with error %d\n", 1111 + name, ret); 1112 + if (opt_flags & FW_OPT_USERHELPER) { 1113 1113 dev_warn(device, "Falling back to user helper\n"); 1114 1114 ret = fw_load_from_user_helper(fw, name, device, 1115 1115 opt_flags, timeout); ··· 1167 1165 } 1168 1166 EXPORT_SYMBOL(request_firmware); 1169 1167 1170 - #ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK 1171 1168 /** 1172 1169 * request_firmware: - load firmware directly without usermode helper 1173 1170 * @firmware_p: pointer to firmware image ··· 1183 1182 { 1184 1183 int ret; 1185 1184 __module_get(THIS_MODULE); 1186 - ret = _request_firmware(firmware_p, name, device, FW_OPT_UEVENT); 1185 + ret = _request_firmware(firmware_p, name, device, 1186 + FW_OPT_UEVENT | FW_OPT_NO_WARN); 1187 1187 module_put(THIS_MODULE); 1188 1188 return ret; 1189 1189 } 1190 1190 EXPORT_SYMBOL_GPL(request_firmware_direct); 1191 - #endif 1192 1191 1193 1192 /** 1194 1193 * release_firmware: - release the resource associated with a firmware image
+8 -7
include/linux/firmware.h
··· 45 45 struct module *module, bool uevent, 46 46 const char *name, struct device *device, gfp_t gfp, void *context, 47 47 void (*cont)(const struct firmware *fw, void *context)); 48 + int request_firmware_direct(const struct firmware **fw, const char *name, 49 + struct device *device); 48 50 49 51 void release_firmware(const struct firmware *fw); 50 52 #else ··· 68 66 { 69 67 } 70 68 71 - #endif 69 + static inline int request_firmware_direct(const struct firmware **fw, 70 + const char *name, 71 + struct device *device) 72 + { 73 + return -EINVAL; 74 + } 72 75 73 - #ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK 74 - int request_firmware_direct(const struct firmware **fw, const char *name, 75 - struct device *device); 76 - #else 77 - #define request_firmware_direct request_firmware 78 76 #endif 79 - 80 77 #endif