aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/firmware_class.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/firmware_class.c')
-rw-r--r--drivers/base/firmware_class.c47
1 files changed, 22 insertions, 25 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index d276e33880be..da77791793f1 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -100,10 +100,16 @@ static inline long firmware_loading_timeout(void)
100#define FW_OPT_UEVENT (1U << 0) 100#define FW_OPT_UEVENT (1U << 0)
101#define FW_OPT_NOWAIT (1U << 1) 101#define FW_OPT_NOWAIT (1U << 1)
102#ifdef CONFIG_FW_LOADER_USER_HELPER 102#ifdef CONFIG_FW_LOADER_USER_HELPER
103#define FW_OPT_FALLBACK (1U << 2) 103#define FW_OPT_USERHELPER (1U << 2)
104#else 104#else
105#define FW_OPT_FALLBACK 0 105#define FW_OPT_USERHELPER 0
106#endif 106#endif
107#ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK
108#define FW_OPT_FALLBACK FW_OPT_USERHELPER
109#else
110#define FW_OPT_FALLBACK 0
111#endif
112#define FW_OPT_NO_WARN (1U << 3)
107 113
108struct firmware_cache { 114struct firmware_cache {
109 /* firmware_buf instance will be added into the below list */ 115 /* firmware_buf instance will be added into the below list */
@@ -279,26 +285,15 @@ static const char * const fw_path[] = {
279module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); 285module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644);
280MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); 286MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path");
281 287
282/* Don't inline this: 'struct kstat' is biggish */
283static noinline_for_stack int fw_file_size(struct file *file)
284{
285 struct kstat st;
286 if (vfs_getattr(&file->f_path, &st))
287 return -1;
288 if (!S_ISREG(st.mode))
289 return -1;
290 if (st.size != (int)st.size)
291 return -1;
292 return st.size;
293}
294
295static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) 288static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
296{ 289{
297 int size; 290 int size;
298 char *buf; 291 char *buf;
299 int rc; 292 int rc;
300 293
301 size = fw_file_size(file); 294 if (!S_ISREG(file_inode(file)->i_mode))
295 return -EINVAL;
296 size = i_size_read(file_inode(file));
302 if (size <= 0) 297 if (size <= 0)
303 return -EINVAL; 298 return -EINVAL;
304 buf = vmalloc(size); 299 buf = vmalloc(size);
@@ -718,7 +713,7 @@ out:
718static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) 713static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
719{ 714{
720 struct firmware_buf *buf = fw_priv->buf; 715 struct firmware_buf *buf = fw_priv->buf;
721 int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT; 716 int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT;
722 717
723 /* If the array of pages is too small, grow it... */ 718 /* If the array of pages is too small, grow it... */
724 if (buf->page_array_size < pages_needed) { 719 if (buf->page_array_size < pages_needed) {
@@ -911,7 +906,9 @@ static int _request_firmware_load(struct firmware_priv *fw_priv,
911 wait_for_completion(&buf->completion); 906 wait_for_completion(&buf->completion);
912 907
913 cancel_delayed_work_sync(&fw_priv->timeout_work); 908 cancel_delayed_work_sync(&fw_priv->timeout_work);
914 if (!buf->data) 909 if (is_fw_load_aborted(buf))
910 retval = -EAGAIN;
911 else if (!buf->data)
915 retval = -ENOMEM; 912 retval = -ENOMEM;
916 913
917 device_remove_file(f_dev, &dev_attr_loading); 914 device_remove_file(f_dev, &dev_attr_loading);
@@ -1111,10 +1108,11 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
1111 1108
1112 ret = fw_get_filesystem_firmware(device, fw->priv); 1109 ret = fw_get_filesystem_firmware(device, fw->priv);
1113 if (ret) { 1110 if (ret) {
1114 if (opt_flags & FW_OPT_FALLBACK) { 1111 if (!(opt_flags & FW_OPT_NO_WARN))
1115 dev_warn(device, 1112 dev_warn(device,
1116 "Direct firmware load failed with error %d\n", 1113 "Direct firmware load for %s failed with error %d\n",
1117 ret); 1114 name, ret);
1115 if (opt_flags & FW_OPT_USERHELPER) {
1118 dev_warn(device, "Falling back to user helper\n"); 1116 dev_warn(device, "Falling back to user helper\n");
1119 ret = fw_load_from_user_helper(fw, name, device, 1117 ret = fw_load_from_user_helper(fw, name, device,
1120 opt_flags, timeout); 1118 opt_flags, timeout);
@@ -1171,7 +1169,6 @@ request_firmware(const struct firmware **firmware_p, const char *name,
1171} 1169}
1172EXPORT_SYMBOL(request_firmware); 1170EXPORT_SYMBOL(request_firmware);
1173 1171
1174#ifdef CONFIG_FW_LOADER_USER_HELPER
1175/** 1172/**
1176 * request_firmware: - load firmware directly without usermode helper 1173 * request_firmware: - load firmware directly without usermode helper
1177 * @firmware_p: pointer to firmware image 1174 * @firmware_p: pointer to firmware image
@@ -1188,12 +1185,12 @@ int request_firmware_direct(const struct firmware **firmware_p,
1188{ 1185{
1189 int ret; 1186 int ret;
1190 __module_get(THIS_MODULE); 1187 __module_get(THIS_MODULE);
1191 ret = _request_firmware(firmware_p, name, device, FW_OPT_UEVENT); 1188 ret = _request_firmware(firmware_p, name, device,
1189 FW_OPT_UEVENT | FW_OPT_NO_WARN);
1192 module_put(THIS_MODULE); 1190 module_put(THIS_MODULE);
1193 return ret; 1191 return ret;
1194} 1192}
1195EXPORT_SYMBOL_GPL(request_firmware_direct); 1193EXPORT_SYMBOL_GPL(request_firmware_direct);
1196#endif
1197 1194
1198/** 1195/**
1199 * release_firmware: - release the resource associated with a firmware image 1196 * release_firmware: - release the resource associated with a firmware image
@@ -1277,7 +1274,7 @@ request_firmware_nowait(
1277 fw_work->context = context; 1274 fw_work->context = context;
1278 fw_work->cont = cont; 1275 fw_work->cont = cont;
1279 fw_work->opt_flags = FW_OPT_NOWAIT | FW_OPT_FALLBACK | 1276 fw_work->opt_flags = FW_OPT_NOWAIT | FW_OPT_FALLBACK |
1280 (uevent ? FW_OPT_UEVENT : 0); 1277 (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER);
1281 1278
1282 if (!try_module_get(module)) { 1279 if (!try_module_get(module)) {
1283 kfree(fw_work); 1280 kfree(fw_work);